I have encountered some errors when using Lwt_main.run()
. Basically I have two infinite loops with type unit -> 'a Lwt.t = <fun>
and when I start both loops I receive errors. I am using these in the context that one loop is a writer loop and the other is a reader loop. Basically I have to update some data with the writer much more often than I use it with the reader. The errors I receive can be illustrated with the code below.
let rec p1 () =
Lwt_io.print "1\n"
>>= fun () -> Lwt_unix.sleep 1.0
>>= p1
;;
val p1 : unit -> 'a Lwt.t = <fun>
let rec p5 () =
Lwt_io.print "5\n"
>>= fun () -> Lwt_unix.sleep 5.0
>>= p5
;;
val p5 : unit -> 'a Lwt.t = <fun>
Lwt_main.run(p1(); p5());;
Characters 13-17:
Warning 10: this expression should have type unit.
Characters 13-17:
Warning 10: this expression should have type unit.
I can run the Lwt_main.run statements as follows without errors but it seems that this solution is just masking the warning with the wildcard instead of fixing the warning.
let _ = Lwt_main.run(p1())
let _ = Lwt_main.run(p5())
What is the proper use of Lwt_main.run()
in this context so that I can fix the errors instead of just masking them with the wildcard character?
First of all it is not an error, but warning. It states that expression that is terminated with
;
doesn't evaluate to a value of typeunit
as expected. In your case you have two expressionsp1 ()
that evaluates tounit Lwt.t
andp5 ()
that evaluates to the same type. Obviously they do not have typeunit
, so that you can't put;
afterp1 ()
orp5 ()
. Since both of them are lwt threads, and what you want (I suspect) is to run them in parallel, then you need to useLwt.pick
function, or its infix equivalent<&>
:On the other hand, if you want to serialize this threads, i.e., to run one after another, not in parallel, then you need to bind them using
>>=
operation, or, if you have enabled syntax support, then you can use>>
syntax, thats actually stands for monadic semicolon.