我浏览了一篇文章( http://comonad.com/reader/2012/abstracting-with-applicatives/ )并在那里找到了以下代码片段:
newtype Compose f g a = Compose (f (g a)) deriving Show
instance (Functor f, Functor g) => Functor (Compose f g) where
fmap f (Compose x) = Compose $ (fmap . fmap) f x
(fmap . fmap)
实际上如何进行类型检查?
它们的类型是:
(.) :: (a -> b) -> (r -> a) -> (r -> b)
fmap :: (a -> b) -> f a -> f b
fmap :: (a -> b) -> f a -> f b
现在从这里我根本看不到 fmap . fmap
会进行类型检查吗?
最佳答案
首先让我们将类型变量的名称更改为唯一:
(.) :: (a -> b) -> (r -> a) -> (r -> b)
fmap :: Functor f => (c -> d) -> f c -> f d
fmap :: Functor g => (x -> y) -> g x -> g y
现在 .
的第一个参数的类型为 a -> b
,我们提供一个类型为 (c -> d) -> (f c -> f d)
,因此 a
是 c -> d
,b
是 f c -> f d
。到目前为止我们已经:
(.) :: Functor f => -- Left operand
((c -> d) -> (f c -> f d)) ->
-- Right operand
(r -> (c -> d)) ->
-- Result
(r -> (f c -> f d))
.
的第二个参数具有类型 r -> a
又名 r -> (c -> d)
以及我们给出的参数具有类型 (x -> y) -> (g x -> g y)
,因此 r
变为 x -> y
, c
变为 g x
,d
变为 g y
。所以现在我们有:
(.) :: (Functor f, Functor g) => -- Left operand
((g x -> g y) -> (f (g x) -> f (g y))) ->
-- Right operand
((x -> y) -> (g x -> g y)) ->
-- Result
(x -> y) -> f (g x) -> f (g y)
fmap.fmap :: (Functor f, Functor g) => (x -> y) -> f (g x) -> f (g y)
关于haskell - (fmap . fmap) 如何进行类型检查,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23030638/