如何用英语阅读函数类型

时间:2012-12-11 15:59:25

标签: f#

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)

任何人都可以教我如何阅读撰写的功能类型

2 个答案:

答案 0 :(得分:7)

根据您的使用方式,有多种方法可以读取函数类型。但是如果你以你的例子(compose plus1 mal2)中演示的方式使用它,那么下面的阅读是有道理的:

compose是一个函数:

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

    的函数的函数LI>
  • 接受另一个参数'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);

这是两个参数xy的函数,它返回值z

在功能性世界中,val compose: 'x -> 'y -> 'z可能会以两种截然不同的方式被考虑:

  1. 两个参数'x'y的函数,返回'z
  2. 一个参数'x的函数,返回函数,而函数依次为{{>一个参数{{ 1}}并返回'y
  3. 此过程称为部分应用

    返回原来的'z,可以通过两种方式阅读:

    1. 正如Tomas所描述的那样:一个功能
      • 相应地采用两个参数,val compose : ('b -> 'c) -> ('a -> 'b) -> ('a -> 'c)('b -> 'c);
      • 返回类型('a -> 'b)
      • 的函数
    2. 或者,或者,一个功能
      • 采取一个参数('a -> 'c)
      • 返回一个函数
        • 采取一个参数('b -> 'c)
        • 返回类型('a -> 'b)
        • 的函数