代码之家  ›  专栏  ›  技术社区  ›  Grzegorz Wierzowiecki

如何习惯性地使用bimap?也许还有别的东西可以用两个函数来映射元素

  •  0
  • Grzegorz Wierzowiecki  · 技术社区  · 7 年前

    如何在列表上应用两个函数 Either a b 用更惯用的方式(我想可能是 bimap 对吗?(不使用 instance ... where 正如我想灵活的“一次性”的应用程序不同 f g 功能-> biEitherTransformGenerator biEitherFmap 允许一行)

    我试着用 bimap软件 将两个函数映射到 不是a b :

    biEitherTransformGenerator :: (a->c) -> (b->d) -> Either a b -> Either c d
    biEitherTransformGenerator f g (Left x) = Left $ f x
    biEitherTransformGenerator f g (Right x) = Right $ g x
    biEitherFmap :: (Functor container) => (a->c) -> (b->d) -> container (Either a b) -> container (Either c d)
    biEitherFmap f g = fmap $ biEitherTransformGenerator f g
    el = [Left 5, Right "foo", Left 10, Right "bar"]:: [Either Int [Char]]
    main = do
        print el
        let l1 = fmap (biEitherTransformGenerator (*2) (++"!!!")) el
        print l1
        let l2 = biEitherFmap (*2) (++"!!!") el
        print l2
        print $ l1 == l2
        -- let l3 = fmap (bimap (*2) (++"!!!")) el
        -- print l3
    

    输出 runhaskell DoubleFunctor.hs :

    [Left 5,Right "foo",Left 10,Right "bar"]
    [Left 10,Right "foo!!!",Left 20,Right "bar!!!"]
    [Left 10,Right "foo!!!",Left 20,Right "bar!!!"]
    True
    

    每次我取消注释最后两行时:

    let l3 = fmap (bimap (*2) (++"!!!")) el
    print l3
    

    我得到:

    DoubleFunctor.hs:14:20: error:
        Variable not in scope:
          bimap
            :: (Integer -> Integer)
               -> ([Char] -> [Char]) -> Either Int [Char] -> b
       |
    14 |     let l3 = fmap (bimap (*2) (++"!!!")) el
       |                    ^^^^^
    

    我想达到的目标:更具个性的做事方式 fmap (biEitherTransformGenerator f g) listOfEither biEitherFmap f g listOfEither .

    1 回复  |  直到 7 年前
        1
  •  6
  •   chepner    7 年前

    这个 Bifunctor 类不是前奏曲的一部分;您需要从 Data.Bifunctor 第一。(根据您的安装,模块可能由 base 库,或者您可能需要安装 bifunctors 图书馆优先。)

    Prelude> :t bimap
    
    <interactive>:1:1: error: Variable not in scope: bimap
    Prelude> import Data.Bifunctor
    Prelude Data.Bifunctor> :t bimap
    bimap :: Bifunctor p => (a -> b) -> (c -> d) -> p a c -> p b d
    Prelude Data.Bifunctor> el = [Left 5, Right "foo", Left 10, Right "bar"]
    Prelude Data.Bifunctor> fmap (bimap (*2) (++"!!!")) el
    [Left 10,Right "foo!!!",Left 20,Right "bar!!!"]
    
    推荐文章