为什么类型推断算法由于'Fun.flip Option.bind'而引起混淆?

问题描述 投票:0回答:1

模块中函数声明的通用签名是最后一个参数具有主要状态类型(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)时。就像在“列表”模块中一样。这种形式可以使用'|>'...

ocaml type-inference
1个回答
0
投票

您的问题是您对opt_bind的定义不够多态。由于您将其定义为应用程序(Fun.flip至Option.bind),因此由于值限制而不能使其变为多态。

© www.soinside.com 2019 - 2024. All rights reserved.