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)
谁能教我如何阅读撰写的功能类型
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)
谁能教我如何阅读撰写的功能类型
有多种方法可以读取函数类型,具体取决于您如何使用它。但是,如果您以示例 ( compose plus1 mal2
) 中演示的方式使用它,那么以下阅读是有意义的:
compose
是一个函数:
接受一个参数,该参数'b -> 'c
本身就是一个知道如何将类型值'b
转换为不同类型值的函数'c
接受另一个参数'a -> 'b
,它(再次)是一个可以将值'a
转换为 type 值的函数'b
。
给定这两个函数,可以按顺序运行它们——如果你有一个值'a
,你可以应用第二个函数来获取一个类型的值,'b
这个值可以传递给第一个函数来获取'c
。这正是compose
这样做的:
'a
并产生'c
(只能通过将第二个函数'a
应用于结果然后将第一个函数应用于结果来完成)Tomas 的回答是绝对正确的,但它不包括currying。
为了更好地理解什么是柯里化函数,看看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
,返回一个函数,该函数又将接受一个参数'y
并返回'z
。这个过程称为部分应用。
回到原来val compose : ('b -> 'c) -> ('a -> 'b) -> ('a -> 'c)
的 ,可以通过两种方式阅读:
('b -> 'c)
和 ('a -> 'b)
, 相应地;('a -> 'c)
('b -> 'c)
('a -> 'b)
('a -> 'c)