3
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)

谁能教我如何阅读撰写的功能类型

4

2 回答 2

7

有多种方法可以读取函数类型,具体取决于您如何使用它。但是,如果您以示例 ( compose plus1 mal2) 中演示的方式使用它,那么以下阅读是有意义的:

compose是一个函数:

  • 接受一个参数,该参数'b -> 'c本身就是一个知道如何将类型值'b转换为不同类型值的函数'c

  • 接受另一个参数'a -> 'b,它(再次)是一个可以将值'a转换为 type 值的函数'b

给定这两个函数,可以按顺序运行它们——如果你有一个值'a,你可以应用第二个函数来获取一个类型的值,'b这个值可以传递给第一个函数来获取'c。这正是compose这样做的:

  • 结果是一个组合函数,它接受'a并产生'c(只能通过将第二个函数'a应用于结果然后将第一个函数应用于结果来完成)
于 2012-12-11T16:04:23.500 回答
3

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可以以两种本质上不同的方式来考虑:

  1. 一个有两个参数'x和的函数'y,返回'z
  2. 一个有一个参数的函数'x,返回一个函数,该函数又将接受一个参数'y并返回'z

这个过程称为部分应用

回到原来val compose : ('b -> 'c) -> ('a -> 'b) -> ('a -> 'c)的 ,可以通过两种方式阅读:

  1. 正如 Tomas 所描述的那样:一个函数
    • 接受两个参数,('b -> 'c)('a -> 'b), 相应地;
    • 返回类型的函数('a -> 'c)
  2. 或者,或者,一个函数
    • 接受一个论点('b -> 'c)
    • 返回一个函数
      • 接受一个论点('a -> 'b)
      • 返回类型的函数('a -> 'c)
于 2012-12-11T16:22:52.243 回答