首先,我们来写_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
aanda1是两个不同的类型变量,就像band一样b1。但是由于最终类型中没有bor c,我们可以重命名b1并c1返回 just band 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' 定义的两次应用(我们总是可以在那里添加我们需要的任意数量的参数)。