
Hi, On 01/24/2018 12:02 PM, Jean-Marc Alliot wrote:
First thanks again for the answer, I really appreciate.
You're welcome, I'm happy to help!
module IOMonad = struct type 'a t = IO of 'a;; let return x = IO x;; let (>>=) (IO m) (f : ('a -> 'b t)) = (f m);; end;; open IOMonad;;
The closest thing to Haskell's (IO a) in OCaml is (unit -> 'a). module IOMonad = struct type 'a t = unit -> 'a let return x = fun () -> x let (>>=) m f = fun () -> f (m ()) () end I believe that definition will result in the same looping behavior as with the original Haskell program. It's not really a matter of laziness, but more of (im)purity. In OCaml, functions can have side effects. In Haskell, we must write pure functions that return an effectful computation as a value. In particular, we have the following property in Haskell: let a = print 1 in a >> a -- a :: IO () is equivalent to print 1 >> print 1 because "a" stands for the computation that prints 1 and returns (). Whereas in OCaml: let a = print_int 1 in a; a is not equivalent to print_int 1; print_int 1 here "a" just stands for (), and the effect is performed before it is evaluated. But we can define (print : int -> IO.t ()) as (let print n () = print_int n) in OCaml, with compositional properties similar to Haskell's print. Li-yao