Search code examples
ocaml

How to use let* Monad syntax for Lists


I'm playing around with OCaml's let* syntax but I can't get anything to work when working with Lists. When I try to define a (not very useful) dupe function like this:

let (let*) = List.concat_map

let dupe xs = let* f = (fun a -> [a;a]) xs in f

It fails to compile with error:

The operator let* has type ('a -> 'b list) -> 'a list -> 'b list
       but it was expected to have type ('a -> 'b list) -> ('c -> 'd) -> 'e
       Type 'a list is not compatible with type 'c -> 'd

I don't understand why the compiler seems to think my xs variable is of type ('c -> 'd). Explicitly defining the type as in (xs: 'a list) in the method definition doesn't help. What am I doing wrong?


Solution

  • The concat_map function has type ('a -> 'b list) -> 'a list -> 'b list, in other words it expects the map function first contrarily to the bind function. In other words, the arguments order need to be reversed to define (let*):

    let (let*) m body = List.concat_map body m
    let dupe xs = let* f = [xs;xs] in f