繁体   English   中英

fmap的功能组成

[英]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 您可以使用fmapfmap ffmap 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM