我正在学习函数式编程,但我不了解 OCaml 中的类型,而且我没有发现任何真正有用的东西。
我有这个代码:
let rec map2 f l1 l2 =
match (l1,l2) with
([], _) -> []
| (_, []) -> []
| (x::l1s,y::l2s) -> (f x y) :: map2 f l1s l2s;;
let pick n m =
if n > m then (fun b x -> if b then x+1 else x*2)
else (fun b x -> if b then x+2 else x*4);;
map2 (pick 7 9) [true;false] [3;4;5;6];;
我觉得很难理解了解这类函数类型的步骤(map2、pick)。
我知道一些签名是如何工作的,正确的关联属性以及符号“ ' ”是指泛型类型。
解决方案:
pick: 'a -> 'a -> bool -> int -> int = <fun>
map2: ('a->'b->'c) -> 'a list -> 'b list -> 'c list
我不明白为什么 bool -> int 以及为什么 map bool 不在函数参数中。
欢迎任何参考书籍、链接
pick: 'a -> 'a -> bool -> int -> int = <fun>
map2: ('a->'b->'c) -> 'a list -> 'b list -> 'c list
您在此处看到的是函数式编程中的一个过程,称为currying。为了理解这一点,让我们考虑一个更简单的例子。假设您有一个函数f
,它接受 2 个参数X
andY
和 output Z
。我们通常这样写
f(X, Y) = Z
让我们以不同的方式看待这一点 - 我们有一个函数f
,如果我们给它X
,然后Y
它就会给我们Z
。如果我们只给出f
1 个参数,会发生什么X
?让我们来测试一下!
let plus a b = a + b;;
该代码定义了一个函数plus
,它需要两个参数a
和b
并返回它们的总和。如果您键入plus 1 1;;
到utop
,它会给你2
。现在,键入时的输出
plus 1;;
是
- : int -> int = <fun>
这意味着plus(1)
实际上产生了一个 FUNCTION,它接受一个int
并输出一个int
! 等一下,最初我们有一个产生整数的函数,突然同一个函数产生了...... FUNCTION?这是怎么回事?
这里的关键思想是将函数视为一个一个一个地使用参数的过程。本着这种精神,plus
上面的函数就像一个消耗 2 个参数的过程:如果你只给它 1 个参数,它会停止并等待第二个参数。这个停滞的过程与消耗 1 个参数的过程完全相似:给它剩余的成分,它会开始研磨以给你预期的输出。
要了解这种观点如何帮助您理解示例中编写函数签名的晦涩方式,让我们看一下函数pick
:
let pick n m =
if n > m then (fun b x -> if b then x+1 else x*2)
else (fun b x -> if b then x+2 else x*4);;
pick
接受 2 个参数n
和m
,并输出一个f
接受 2 个参数b
和的函数x
。的定义f
取决于比较。如果n > m
,则输出一个fun b x
定义为的函数if b then x+1 else x*2
。否则,它输出一个fun b x
定义为的函数if b then x+2 else x*4
。
如果我们pick
根据上面的理解写一个粗略的签名,它会是这样的:
pick: (n, m) -> (function f that takes in b and x, and output some number)
根据我们对柯里化的理解,pick
就像一个消耗n
,然后 的过程m
。所以签名也可以这样写:
pick: n -> m -> (function f that takes in b and x, and output some number)
哦嘿嘿,这个函数f
也可以看成是一个消费b
然后的过程x
,所以我们也可以这样写:
pick: n -> m -> (b -> x -> some number)
看起来非常相似:
pick: 'a -> 'a -> bool -> int -> int = <fun>
现在,作为的到底是如何知道ocaml的b
应该是bool
,而且x
和some number
被认为是int
,OCaml有一个有特色的称为类型推断。基本上,编译器会查看您对变量执行的操作并尝试猜测它们的类型。例如,我if b
在代码中看到,所以可能b
应该是bool
.
总之,编写函数签名的那种晦涩难懂的方式称为currying,而 OCaml 如何知道b
abool
是通过OCaml 中称为类型推断的功能。这应该使搜索更容易。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句