模块中函数声明的通用签名是最后一个参数具有主要状态类型(Module.t)时。就像在“列表”模块中一样。这种形式可以使用'|>'运算符,例如:
[1;2;3] |> List.filter ((>)2)
|> List.map ((-)1)
|> List.fold_left 0 (+)
但是'Option'模块中的'bind'函数不遵循这种形式。它的第一个参数为“ 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。类型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 opt_bind (type x)(type y) : (x -> y option) -> (x option) -> (y option) = Fun.flip Option.bind
无济于事。
但是
let result = let x = Option.bind (Some 42) f in let x = Option.bind x g in x
工作正常。
为什么'opt_bind'对'g'的类型期望值错误,好像'opt_bind'不是通用的?如何使用带有'|>'表示法的'bind'?
模块中函数声明的通用签名是最后一个参数具有主要状态类型(Module.t)时。就像在“列表”模块中一样。这种形式可以使用'|>'...
您的问题是您对opt_bind
的定义不够多态。由于您将其定义为应用程序(Fun.flip至Option.bind),因此由于值限制而不能使其变为多态。