我开始学习函数式编程(OCaml),但我不理解关于函数式编程的一个重要主题:类型。
有人能解释一下这个解决方案吗?
本周进行测试,无法达到分辨率。
let f a b c = a (a b c) 0;;
f: ('a -> int -> 'a) -> 'a -> int -> 'a
答案 0 :(得分:4)
let f a b c = a (a b c) 0;;
您的困惑涉及类型和类型推断,即,当您定义函数或绑定时,您不需要为其参数提供显式类型,也不需要为函数/绑定本身提供显式类型,如果您定义的话,OCaml将会弄清楚功能/绑定是正确的。
所以,让我们自己做一些手动推理。如果一个人可以做,那么编译器也可以这样做。
<强> 1 强>
let x = 1
1
是整数,因此x必须是整数。所以你不需要像其他语言一样int x = 1
,对吗?
<强> 2 强>
let f x = 1
如果let
和=
之间有多个变量名,那么它必须是函数定义,对吧?否则,它没有意义。在Java语言中,说int x y = 1
也没有意义,对吗?
所以f
是一个函数,x必须是一个参数。由于=
的右侧是整数,因此我们知道f
将返回一个整数。对于x,我们不知道,因此x
将被视为多态类型'a
。
所以f: 'a -> int = <fun>
。
第3 强>
let f a b c = a (a b c) 0;;
f
是一个函数,参数为a
,b
,c
。
a
必须是一个函数,因为在=
的右侧,它是一个函数应用程序。
a
有两个参数:(a b c)
和0. 0
是一个整数,因此a
的第二个参数必须是整数类型。
查看(a b c)
内部,c
是第二个争论,因此c
必须是整数。
我们无法推断b
。因此b
是'a
。
由于(a b c)
可以是a
的第一个参数,而(a b c)
本身是函数a
上的应用程序,因此a
的返回类型} b
具有相同类型的'a
。
将上述信息合并在一起,即可获得f: ('a -> int -> 'a) -> 'a -> int -> 'a
。
如果您想正式学习,https://realworldocaml.org/是您的朋友。