Haskell中的合成
我最近在学习Haskell,我在读《向你学习Haskell》中的函子,我是从中认识的Haskell中的合成,haskell,functional-programming,functor,Haskell,Functional Programming,Functor,我最近在学习Haskell,我在读《向你学习Haskell》中的函子,我是从中认识的 函数((->)r)采用一个参数,在某种程度上也是函子 合成()相当于fmap 根据我的理解,fmap有两个参数。第一个是要应用的函数,第二个是函子 但是,我对这个表达式感到困惑。这是一个由两个组合组成的组合,类型为(b->c)->(a1->a2->b)->(a1->a2->c) 因此,我产生了怀疑。第一个()有两个参数,第一个是合成函数本身。第二个参数也是合成函数。复合函数本身不是函子。那么这是一个怎样的有效表
((->)r)
采用一个参数,在某种程度上也是函子()
相当于fmap
(b->c)->(a1->a2->b)->(a1->a2->c)
因此,我产生了怀疑。第一个()
有两个参数,第一个是合成函数本身。第二个参数也是合成函数。复合函数本身不是函子。那么这是一个怎样的有效表达式呢
我确信我在这里遗漏了一些东西。有人能填补空白并帮助我了解表达式的正确性吗?忽略
((->)r
的函子实例;这无关紧要。这里只有两个问题:类型()
,即
(.) :: (b -> c) -> (a -> b) -> a -> c
,函数应用程序是左关联的。后者意味着()(
与(()()(
相同
让我们首先尝试查找(..
)的类型(如果您愿意,请选择最左边的)。让我们把第一个()
的类型写成(b1->c1)->(a1->b1)->a1->c1
,第二个写成(b2->c2)->(a2->b2)->a2->c2
。我们将第一个应用于第二个,这使我们知道b1
是(b2->c2)
,c1
是(a2->b2)->a2->c2
。因此,我们有
(.) (.) :: (a1 -> (b2 -> c2)) -> a1 -> ((a2 -> b2) -> a2 -> c2)
可以简化为
(.) (.) :: (a1 -> b2 -> c2) -> a1 -> (a2 -> b2) -> a2 -> c2
现在,让我们将此应用于最后一个()
(如果您愿意,最右边的一个)。如果它有签名(b3->c3)->(a3->b3)->a3->c3
,那么我们看到a1
必须是(b3->c3)
,b2
必须是(a3->b3)
,c2
必须是a3->c3
。因此,
((.) (.)) (.) :: (b3 -> c3) -> (a2 -> (a3 -> b3)) -> a2 -> a3 -> c3
这和
((.) (.)) (.) :: (b3 -> c3) -> (a2 -> a3 -> b3) -> (a2 -> a3 -> c3)
如果您进行了一些重命名,这与您在问题中遇到的情况相同。这里有些混乱。函数是值,而函子是将类型映射到类型的类型级对象。应用程序(.)
可以理解,而不必考虑函子。