[Haskell-cafe] I really don't understand this

Li-yao Xia lysxia at gmail.com
Wed Jan 24 17:52:24 UTC 2018


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


More information about the Haskell-Cafe mailing list