功能构成
函数组合运算符 (.)
定义为
(.) :: (b -> c) -> (a -> b) -> (a -> c)
(.) f g x = f (g x) -- or, equivalently,
(.) f g = \x -> f (g x)
(.) f = \g -> \x -> f (g x)
(.) = \f -> \g -> \x -> f (g x)
(.) = \f -> (\g -> (\x -> f (g x) ) )
类型 (b -> c) -> (a -> b) -> (a -> c)
可以写成 (b -> c) -> (a -> b) -> a -> c
,因为类型签名中的 ->
关联到右边,对应于与左边相关联的函数应用程序,
f g x y z ... == (((f g) x) y) z ...
所以数据流是从右到左:x
进入g
,其结果进入 f
,产生最终结果:
(.) f g x = r
where r = f (g x)
-- g::a -> b
-- f :: b -> c
-- x::a
-- r :: c
(.) f g = q
where q = \x -> f (g x)
-- g::a -> b
-- f :: b -> c
-- q::a -> c
....
从语法上讲,以下都是相同的:
(.) f g x = (f . g) x = (f .) g x = (. g) f x
这很容易被理解为“ 运算符部分的三个规则 ”,其中缺失的参数只是进入运算符附近的空槽:
(.) f g = (f . g) = (f .) g = (. g) f
-- 1 2 3
可以省略存在于等式两侧的 x
。这被称为 eta 收缩。因此,写下函数组合定义的简单方法就是
(f . g) x = f (g x)
这当然是指论证x
; 每当我们在没有 x
的情况下编写 (f . g)
时,它就被称为无点样式。