Обычная сигнатура объявлений функций в модуле - это когда последний параметр имеет тип основного состояния (Module.t). Как в модуле «Список». Эта форма открывает возможность использования оператора '|>', например:
[1;2;3] |> List.filter ((>)2)
|> List.map ((-)1)
|> List.fold_left 0 (+)
Но функция 'bind' в модуле 'Option' не следует этой форме. Он имеет параметр «Option.t» в качестве первого
val bind : 'a option -> ('a -> 'b option) -> 'b option
Но хорошо, я могу его изменить. Я объявил функцию opt_bind с обратным порядком параметров.
let opt_bind = Fun.flip Option.bind
Но эта не работает. И следующий код был скомпилирован со следующей ошибкой
type a = A of int
type b = B of int
let f x = Some (A x)
let g (A x) = Some (B x)
let opt_bind = Fun.flip Option.bind
let result =
(Some 42) |> opt_bind f
|> opt_bind g
|> opt_bind g
^
Ошибка: это выражение имеет параметр типа a -> b, но ожидалось выражение> типа int -> параметр. Тип a несовместим с типом int
Такая же ситуация с
let result =
let x = opt_bind f (Some 42) in
let x = opt_bind g x in
x
Даже после того, как я заметил все типы, у меня все еще есть та же проблема.
let f : int -> a option = fun x -> Some (A x)
let g : a -> b option = fun (A x) -> Some (B x)
let opt_bind : ('a -> 'b option) -> 'a option -> 'b option =
Fun.flip Option.bind
let result : b option =
let x : a option = opt_bind f (Some 42) in
let x : b option = opt_bind g x in
x ;;
Но
let result =
let x = Option.bind (Some 42) f in
let x = Option.bind x g in
x
работает нормально.
Почему 'opt_bind' имеет неправильное ожидание типа для 'g', как будто 'opt_bind' не является универсальным c?
Как использовать 'bind' с нотацией '|>'?