首先,我们来写_B f g x = f (g x) = (f . g) x
。
既然f $ x = f x
,我们有(.)$(.) = _B $ _B = _B _B
。它的类型是机械派生的,如
0. (.) :: ( b -> c ) -> ((a -> b) -> (a -> c))
1. (.) :: (b1 -> c1) -> ((a1 -> b1) -> (a1 -> c1))
2. (.) (.) :: {b ~ b1 -> c1, c ~ (a1 -> b1) -> (a1 -> c1)} (a -> b) -> (a -> c)
:: (a -> b1 -> c1) -> a -> (a1 -> b1) -> (a1 -> c1)
:: (a -> b -> c ) -> a -> (a1 -> b ) -> a1 -> c
a
anda1
是两个不同的类型变量,就像b
and一样b1
。但是由于最终类型中没有b
or c
,我们可以重命名b1
并c1
返回 just b
and c
,以简化。但不是a1
。
实际上,我们可以读取这种类型:它得到f :: a -> b -> c
一个二进制函数;x :: a
一个参数值、g :: a1 -> b
一个一元函数和另一个值y :: a1
,并以唯一可能的方式组合它们以使类型适合:
f x :: b -> c
g y :: b
f x (g y) :: c
其余的已经回答了。减少通常更容易在组合方程中遵循,例如_B _B f x g y = _B (f x) g y = f x (g y)
,只需通过_B
' 定义的两次应用(我们总是可以在那里添加我们需要的任意数量的参数)。