[英]Function composition of fmap
函数组成的简单定义是:
f ( g x)
要么
(f . g) $ x
现在,我有以下示例:
newtype Compose f g a =
Compose { getCompose :: f (g a) }
deriving (Eq, Show)
instance (Functor f, Functor g) => Functor (Compose f g) where
fmap f (Compose fga) = Compose $ (fmap . fmap) f fga
然后,我尝试编写不带合成运算符的fmap
:
instance (Functor f, Functor g) => Functor (Compose f g) where
fmap f (Compose fga) = Compose $ fmap f (fmap f fga)
编译器抱怨:
* Couldn't match type `b' with `g b'
`b' is a rigid type variable bound by
the type signature for:
fmap :: forall a b. (a -> b) -> Compose f g a -> Compose f g b
at D:\haskell\chapter25\src\Twinplicative.hs:11:5
Expected type: f (g b)
Actual type: f b
* In the second argument of `($)', namely `fmap f (fmap f fga)'
In the expression: Compose $ fmap f (fmap f fga)
In an equation for `fmap':
fmap f (Compose fga) = Compose $ fmap f (fmap f fga)
* Relevant bindings include
fga :: f (g a)
(bound at D:\haskell\chapter25\src\Twinplicative.hs:11:21)
f :: a -> b
(bound at D:\haskell\chapter25\src\Twinplicative.hs:11:10)
fmap :: (a -> b) -> Compose f g a -> Compose f g b
(bound at D:\haskell\chapter25\src\Twinplicative.hs:11:5)
如何在没有合成运算符的情况下撰写以上fmap
?
提供给fmap
最左侧应用程序的fmap
类型应该为fmap
ga -> gb
而提供的f
具有类型fmap
a -> b
。 您可以使用fmap
即fmap f
将fmap
fmap f
a -> b
提升为fmap
ga -> gb
。 外部fmap
的第二个参数应为f (ga)
类型,即fga
的类型:
instance (Functor f, Functor g) => Functor (Compose f g) where
fmap f (Compose fga) = Compose $ fmap (fmap f) fga
我喜欢李的回答,其中明确规定你怎么能实现Functor
实例Compose
自己从头开始。 但是,我也认为有必要回答一个密切相关的问题,那就是:如何从现有实例开始并机械地重写它以避免(.)
函数组合? 因此,我在这个答案中解决了这个问题。
由于(f . g) x = f (gx)
(fmap . fmap) f = fmap (fmap f)
(f . g) x = f (gx)
是(.)
的定义方程,因此我们得出(fmap . fmap) f = fmap (fmap f)
。 将方程的两边应用于fga
,我们得到:
(fmap . fmap) f fga = fmap (fmap f) fga
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.