Сравнение с образцом в утопе является более строгим?

Например, есть функция, которая тестирует, если список монотонно увеличивается, исходный код и варианты тестирования:

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)

Скомпилируйте и запустите код:

$ 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

Однако, когда я хочу использовать эту функцию в Utop, он показывает:

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 

2 ответа

Решение

Вероятно, это связано с открытием вашего верхнего уровня Core, который обеспечивает List.hd который возвращает опцию. В этом конкретном случае вы можете решить эту проблему, изменив способ удаления List.hd полностью:

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

Это потому, что вы открыли модуль Core.Std на верхнем уровне.

Core.Std - это наложение поверх стандартной библиотеки OCaml с другим интерфейсом. Например, в стандартной библиотеке функция List.hd возвращает значение типа 'a и вызывает исключение, если список пуст. В версии Janestreet функция List.hd имеет другой тип - она ​​возвращает параметр, он оценивает None, если список пуст, и значение Some, если это не так. Рассмотреть возможность добавления

open Core.Std

к началу инк.

Другие вопросы по тегам