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)