带有类型变量的实例声明

Pir*_*eax 1 haskell types functor typeclass bifunctor

写这样的东西很好:

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)
Run Code Online (Sandbox Code Playgroud)

现在让我说我要反转这个,左边将f应用于值:

instance Functor (Either a) where
    fmap _ (Right x) = Right x
    fmap f (Left x) = Left (f x)
Run Code Online (Sandbox Code Playgroud)

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

Ale*_*lec 6

你不能,你不应该.如果你能做到这一点,它将使很多强硬知道是否fmap (+1) (Left 1)应该Left 1还是Left 2.

Bifunctor

也就是说,你正在寻找的抽象(可以在任何一方映射的东西)存在并被称为a 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
Run Code Online (Sandbox Code Playgroud)

Flip

另外,如果你想坚持fmap,而不能与被打扰firstsecond,你可以在你的包裹数据类型FlipNEWTYPE,其中有寻找第二类型变量的函数对象实例的效果.你还是靠事实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
Run Code Online (Sandbox Code Playgroud)