Version française
Home     About     Download     Resources     Contact us    
Browse thread
Re: Newbies question
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Markus Mottl <mottl@m...>
Subject: Re: Newbies question
>     let read_res file : ('a * 'b) list =
>       let final_result = ref [] in
>       let fd = open_in file in
>       try 
>         let lexbuf = Lexing.from_channel fd in
>         while true do
>           let result = Parseres.main Lexres.token lexbuf in
>           final_result := result :: !final_result 
>         done  (* <---- nothing returned here, but we cannot get here anyway
>                        the loop is exited by an exception only *) 
>       with             
>         Lexres.Eof ->  
>           close_in fd; !final_result (* !final_result is of type ('a * 'b) list *)
>       | Parsing.Parse_error ->          
>           close_in fd; printf "ERROR: Ressourcen Datei fehlerhaft\n"; exit (-1);

>From the type checker's point of view there are three possible ways out
of your program, but just two can really happen at runtime:

The two exception cases: the first one returns a list of tuples, the second
one exits the program - as you see in the pervasives, "exit" has return
type 'a, so it unifies with any other type (e.g. your tuple list).

Then there is this loop: because there is no return value after it,
it has type "unit" as loops generally do. But "unit" does not unify with a
tuple list.

> But when I use an empty list after the endless-loop, it works alright. Do I
> really have to fake the compiler? Or am I doing something wrong? This works:

Empty lists have type 'a list - this unifies with a tuple list, of course,
and pleases the type checker.

This is perfectly ok, but if you object to this style, you might as well
use a recursive function to parse the input. If you catch exceptions
within it, you can bail out of the recursion at anytime with the final
result.  Thus, there is no need for any extra constructs to please the
type checker and you also don't need any references for accumulating
the final result - just pass on the intermediate result as a parameter
to the recursive function.

By the way, you might also want to use an exception instead of "exit" to
get out of your program. E.g.: failwith "incorrect resource file"

This would allow the calling function to react more appropriately to
such exceptional conditions.

Best regards,
Markus

-- 
Markus Mottl, mottl@miss.wu-wien.ac.at, http://miss.wu-wien.ac.at/~mottl