let compose f g = fun x -> f (g x)
let mal2 x = 2 * x
let plus1 x = x + 1
let mal2Plus1 = compose plus1 mal2
val compose : ('b -> 'c) -> ('a -> 'b) -> ('a -> 'c)
任何人都可以教我如何阅读撰写的功能类型
答案 0 :(得分:7)
根据您的使用方式,有多种方法可以读取函数类型。但是如果你以你的例子(compose plus1 mal2
)中演示的方式使用它,那么下面的阅读是有道理的:
compose
是一个函数:
接受一个参数'b -> 'c
,它本身就是一个知道如何将'b
类型的值转换为'c
类型
接受另一个参数'a -> 'b
,它是(再次)一个可以将值'a
转换为'b
类型值的函数。
给定这两个函数,可以按顺序运行它们 - 如果你有一个值'a
,你可以应用第二个函数来获得类型'b
的值,这个值可以传递获得'c
的第一个函数。这正是compose
所做的:
'a
并生成'c
(只能通过将第二个函数应用于'a
然后将第一个函数应用于结果来完成) 答案 1 :(得分:3)
Tomas的回答绝对正确,但不包括 currying 。
为了更好地理解什么是curry函数,请查看compose
函数并暂时忘记它的参数依次是函数。
我们称他们为'x
,'y
和'z
,以避免与原始代码中的'a
,'b
和'c
混淆:
val compose: 'x -> 'y -> 'z
在命令性的世界中,你会看到类似的东西:
z compose(x theX, y theY);
这是两个参数x
和y
的函数,它返回值z
。
在功能性世界中,val compose: 'x -> 'y -> 'z
可能会以两种截然不同的方式被考虑:
'x
和'y
的函数,返回'z
'x
的函数,返回函数,而函数依次为{{>一个参数{{ 1}}并返回'y
。此过程称为部分应用。
返回原来的'z
,可以通过两种方式阅读:
val compose : ('b -> 'c) -> ('a -> 'b) -> ('a -> 'c)
和('b -> 'c)
; ('a -> 'b)
('a -> 'c)
('b -> 'c)
('a -> 'b)