【问题标题】:Instance declaration with type variables带有类型变量的实例声明
【发布时间】:2017-01-29 03:21:00
【问题描述】:

写这样的东西很好用:

data Either a b = Left a | Right b

instance Functor (Either a) where
    fmap _ (Left x) = Left x
    fmap f (Right x) = Right (f x)

现在假设我想反转这个,Left 将 f 应用于值:

instance Functor (Either a) where
    fmap _ (Right x) = Right x
    fmap f (Left x) = Left (f x)

这不编译,我想我需要像Functor (Either _ b) 这样的东西,我该怎么做?

【问题讨论】:

  • 你不能,至少不能直接。您可以为Either 制作一个newtype 包装器。

标签: haskell types typeclass functor bifunctor


【解决方案1】:

你不能,也不应该。如果你能做到这一点,就很难知道fmap (+1) (Left 1) 应该是Left 1 还是Left 2

Bifunctor

也就是说,您正在寻找的抽象(可以在任一侧映射的东西)存在并且称为Bifunctor。然后,根据您是要映射Lefts 还是Rights,您可以使用firstsecond

ghci> first (+1) (Left 1)
Left 2
ghci> second (+1) (Left 1)
Left 1
ghci> first (+1) (Right 1)
Right 1
ghci> second (+1) (Right 1)
Right 2

Flip

或者,如果你只想坚持fmap而不为firstsecond所困扰,你可以将你的数据类型包装在Flip newtype中,它具有寻找函子的效果第二种类型变量的实例。您仍然依赖EitherBifunctor 的事实,但您避免使用firstsecond

ghci> fmap (+1) (Flip (Left 1))
Flip (Left 2)
ghci> fmap (+1) (Left 1)
Left 1
ghci> fmap (+1) (Flip (Right 1))
Flip (Right 2)
ghci> fmap (+1) (Right 1)
Right 1

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-04-05
    • 2012-11-28
    • 1970-01-01
    • 1970-01-01
    • 2012-03-10
    • 2015-06-28
    • 1970-01-01
    • 2017-01-10
    相关资源
    最近更新 更多