Search code examples
ocamlutop

Pattern matching in utop is more strict?


For example, there is a function that testing if a list is monotonically increasing, the source code and testing cases is:

open Printf

let rec mon_inc (numbers : int list) : bool =
    match numbers with
    | [] -> true
    | _ :: [] -> true
    | hdn :: tln -> (hdn <= (List.hd tln)) && mon_inc(tln)

let a = [1;2;5;5;8]
let b = [1;2;5;4;8]
let c = [8]
let d = []
let e = [7;8]

let () =
    printf "The answer of [1;2;5;5;8]: %B\n" (mon_inc a)

let () =
    printf "The answer of [1;2;5;4;8]: %B\n" (mon_inc b)

let () =
    printf "The answer of [8]: %B\n" (mon_inc c)

let () =
    printf "The answer of []: %B\n" (mon_inc d)

let () =
    printf "The answer of [7;8]: %B\n" (mon_inc e)

Compile and run the code:

$ corebuild inc.native
$ ./inc.native 
The answer of [1;2;5;5;8]: true
The answer of [1;2;5;4;8]: false
The answer of [8]: true
The answer of []: true
The answer of [7;8]: true

However, when I want to use this function in utop, it shows:

utop # #use "inc.ml";;
File "inc.ml", line 7, characters 29-40:
Error: This expression has type int option
but an expression was expected of type int 

Solution

  • This is probably due to your toplevel opening Core, which provides a List.hd that returns an option. In this particular case you can resolve the issue by changing how you match to remove the List.hd entirely:

    let rec mon_inc = function
      | []
      | _::[] -> true
      | x::y::rest -> x <= y && mon_inc rest