函数式编程的核心在于组合
,其中之一就是如何组合函数。咱们在Currying一文就提到过组合,咱们当时是这样描述的:只有一个输入和一个输出的函数才能完成组合,固然并非全部的函数都只有一个输入,Currying能够帮助咱们把多个输入参数的函数变成只有一个输入的函数。
那么到底什么是组合,怎么组合?
给定下面的两个函数:
组合上面的两个函数:
变成下面的函数:
看个例子:编程
let add1 x = x + 1 let multiply2 x = x * 2 let compose g f x = f(g(x))
对应的函数类型为:数组
add1 : x:int -> int multiply2 : x:int -> int compose : g:('a -> 'b) -> f:('b -> 'c) -> x:'a -> 'c
经过compose函数来把add1和multiptly2组合起来:函数式编程
let add1ThenMultiply2 x = compose add1 multiply2
从而获得新的函数:
函数
let result = add1ThenMultiply2 10
既然compose这个函数在F#这么经常使用,不如定义一个操做符>>
来表示:3d
let (>>) f g x = g ( f(x) )
所以上面的代码也能够经过>>来组合:code
let add1ThenMultiply2 x = (>>) add1 multiply2
因为操做符支持中缀表达式,也即操做符能够写在两个参数的中间,例如+号:blog
(+) 1 3
实际上能够写为:ip
1 + 3
那么上面的代码就能够写成:class
let add1ThenMultiply2 x = add1 >> multiply2
上面的例子咱们还能够用管道符来实现:im
let result1 = 10 |> add1 |> multiply2
管道符和组合的定义看起来很是类似:
let (|>) x f = f x let (>>) f g x = g ( f(x) )
管道符(|>)接受两个参数,在往下一个管道符传递的时候已经完成了求值,而函数组合实际上生成了新的函数,最后一步传入实际的参数才会完成求值。
下面的图示描述了管道符的求值过程: