[英]Function composition of fmap
The simple definition of function composition is: 函数组成的简单定义是:
f ( g x)
or 要么
(f . g) $ x
Now I have following example: 现在,我有以下示例:
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
Then I try to write fmap
without composition operator as: 然后,我尝试编写不带合成运算符的fmap
:
instance (Functor f, Functor g) => Functor (Compose f g) where
fmap f (Compose fga) = Compose $ fmap f (fmap f fga)
and the compiler complains: 编译器抱怨:
* 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)
How to compose fmap
above without composition operator? 如何在没有合成运算符的情况下撰写以上fmap
?
The function you provide to the leftmost application of fmap
should have type ga -> gb
while you are providing f
which has type a -> b
. 提供给fmap
最左侧应用程序的fmap
类型应该为fmap
ga -> gb
而提供的f
具有类型fmap
a -> b
。 You can lift a function a -> b
to ga -> gb
using fmap
ie fmap f
. 您可以使用fmap
即fmap f
将fmap
fmap f
a -> b
提升为fmap
ga -> gb
。 The second argument to the outer fmap
should have type f (ga)
which is the type of fga
: 外部fmap
的第二个参数应为f (ga)
类型,即fga
的类型:
instance (Functor f, Functor g) => Functor (Compose f g) where
fmap f (Compose fga) = Compose $ fmap (fmap f) fga
I like Lee's answer, which states clearly how you could implement the Functor
instance for Compose
yourself from scratch. 我喜欢李的回答,其中明确规定你怎么能实现Functor
实例Compose
自己从头开始。 However, I also thought it worth answering a closely related question, which is: how do I start from the existing instance and mechanically rewrite it to avoid the (.)
function composition? 但是,我也认为有必要回答一个密切相关的问题,那就是:如何从现有实例开始并机械地重写它以避免(.)
函数组合? Therefore I tackle that question in this answer. 因此,我在这个答案中解决了这个问题。
Since (f . g) x = f (gx)
is the defining equation of (.)
, we conclude (fmap . fmap) f = fmap (fmap f)
. 由于(f . g) x = f (gx)
(fmap . fmap) f = fmap (fmap f)
(f . g) x = f (gx)
是(.)
的定义方程,因此我们得出(fmap . fmap) f = fmap (fmap f)
。 Applying both sides of the equation to fga
, we get: 将方程的两边应用于fga
,我们得到:
(fmap . fmap) f fga = fmap (fmap f) fga
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.