在Haskell中,Functor具有一个名为
fmap
的函数,其类型为:ghci> :t fmap
fmap :: Functor f => (a -> b) -> f a -> f b
我觉得这很有道理,fmap
将一个从类型 a -> b
的函数提升到类型 f a -> f b
。
那么我很好奇 fmap fmap
的类型是什么,于是我尝试了一下,但结果对我来说很奇怪:
ghci> :t fmap fmap
fmap fmap
:: (Functor f1, Functor f2) => f1 (a -> b) -> f1 (f2 a -> f2 b)
嗯,这种类型有点复杂,但是我可以通过将a
替换为a -> b
,将b
替换为f2 a -> f2 b
来解释它。
然后,我想再进一步:
fmap fmap fmap
:: (Functor f1, Functor f2) => (a -> b) -> f1 (f2 a) -> f1 (f2 b)
哦,等一下!当将 3 个 fmap
放在一起时,事情就变得有趣了。如何解释这个问题呢?
有人可以帮忙解释一下我如何推导出 fmap fmap fmap
的类型吗?
fmap fmap
中的f1
变成了函数函子。也就是说:(->) (a -> b)
在fmap fmap fmap
中。 - lsmorfmap g x
需要x :: f a
。现在在你的情况下,g=fmap :: ...
(现在不重要),而x :: (t->u)-> f2 t -> f2 u
。因此我们需要类型相等f a = (t->u) -> f2 t -> f2 u
,如果我们正确地以前缀形式编写类型构造函数,则变为f a = (->) (t->u) (f2 t -> f2 u)
。然后我们得到f = (->) (t->u)
和a =
f2 t -> f2 u。我认为你可以从这里继续,现在考虑
g=fmap` 的类型。 - chi