Types OCaml中的类型推断

Types OCaml中的类型推断,types,functional-programming,ocaml,ml,Types,Functional Programming,Ocaml,Ml,我正试图理解OCaml的类型推断符号 例如: # let f x = x [];; val f : ('a list -> 'b) -> 'b = <fun> #设fx=x[];; val f:('a list->'b)->'b= 对我来说有道理。val f接受函数x,该函数接受“a类型”列表并返回“b类型”的内容。然后f也返回一个'b类型,因为它只调用x 然而,一旦我们有更多的争论,我就会更加困惑 # let g a b c = a b c;; val g : (

我正试图理解OCaml的类型推断符号

例如:

# let f x = x [];; 
val f : ('a list -> 'b) -> 'b = <fun>
#设fx=x[];;
val f:('a list->'b)->'b=
对我来说有道理。val f接受函数x,该函数接受“a类型”列表并返回“b类型”的内容。然后f也返回一个'b类型,因为它只调用x

然而,一旦我们有更多的争论,我就会更加困惑

# let g a b c = a b c;;
val g : ('a -> 'b -> 'c) -> 'a -> 'b -> 'c = <fun>
#设g a b c=a b c;;
val g:('a->'b->'c)->'a->'b->'c=
我可以假设如果函数有参数,那么类型推断的第一个参数将始终是参数吗?如果我称之为bc,那么顺序是((ab)c)还是(a(bc))

#让rec h m n ls=将ls与
|[]->n
|x:t->hm(mnx)t;;
val h:('a->'b->'a)->'a->'b列表->'a=
至于这一点,我很困惑('a->'b->'a)->'a是如何派生出来的。我可以看到'b list对应于ls变量,最后的'a对应于端子符号n的类型

我可以假设如果函数有参数,那么类型推断的第一个参数将始终是参数吗

是,函数类型的第一个参数是其第一个参数的类型

如果我称之为bc,那么顺序是((ab)c)还是(a(bc))

顺序是
((a b)c)
(你可以用更简单的方式思考)

至于这一点,我很困惑('a->'b->'a)->'a是如何派生出来的。我可以看到'b list对应于ls变量,最后的'a对应于端子符号n的类型

你说得对
ls
具有类型
'b列表
n
具有类型
'a

让我们考虑一下
m
的类型:

  • 您知道
    n
    具有类型
    'a
    ,因此您也可以派生
    (mnx)
    具有类型
    'a
  • 您知道
    ls
    具有类型
    'b list
    ,因此您可以派生
    x
    具有 键入
    'b
  • m
    接受类型为
    'a
    和类型为
    'b
    的两个参数,并生成类型为
    'a
    的结果。因此,
    m
    具有类型
    'a->'b->'a

  • 因此,整个函数的类型为
    ('a->'b->'a)->'a->'b list->'a

    非常感谢!这对我来说很清楚。如果你不介意的话,我还有一个后续问题:如果我们不知道类型推断,只能从方程中找出答案怎么办?你怎么知道m的第二个arg a.k.a.x是“b”类型,与“a”不同?@ChangLiu对于像你这样的简单函数,你可以通过统一来推断。以一种非常简单的方式,分配
    X
    类型的
    m
    Y
    类型的
    n
    Z
    类型的
    ls
    ,等等。然后,为这些变量定义方程,并求解方程以导出大多数主要类型(
    'a
    'b
    ,…)。您可以搜索“算法W”以了解有关类型推断的更多信息。或者,您可以更多地使用OCaml编程,以便更快地在头脑中进行推理:)
    # let rec h m n ls = match ls with
      | [] -> n
      | x::t -> h m (m n x) t;;
    val h : ('a -> 'b -> 'a) -> 'a -> 'b list -> 'a = <fun>