Search code examples
compiler-errorsocamltype-inferenceoperator-precedence

Ocaml - matching two lists


I am trying to write a shuffle function in OCaml, but there is a problem with type inference. Merlin tells me that l1 and l2 are of type 'a list list, which is not true because they are only 'a list. Why does it claims that?

let shuffle l1 l2 =
  let rec scan l1 l2 acc =
    match (l1, l2) with
    | [],[] -> acc
    | ([],h2::t2) -> scan [] t2 h2::acc
    | (h1::t1, []) -> scan t1 [] h1::acc
    | (h1::t1,h2::t2) -> scan t1 t2 h1::h2::acc
  in scan l1 l2 []
;;

Solution

  • The root cause is that operator precedence isn't determined by your grouping by whitespace. That is, scan [] t2 h2::acc is interpreted as (scan [] t2 h2)::acc, not scan [] t2 (h2::acc), because function application has a higher precedence than ::. The fix is simply to add parentheses where appropriate.

    See this table for the precedence and associativity of the different operators in OCaml.