Understanding how Either is an instance of Functor

后端 未结 4 1356
暖寄归人
暖寄归人 2021-02-01 02:11

In my free time I\'m learning Haskell, so this is a beginner question.

In my readings I came across an example illustrating how Either a is made an instance

4条回答
  •  谎友^
    谎友^ (楼主)
    2021-02-01 02:22

    As others mentioned, Either type is a functor in its both arguments. But in Haskell we are able to (directly) define only functors in a type's last arguments. In cases like this, we can get around the limitation by using newtypes:

    newtype FlipEither b a = FlipEither { unFlipEither :: Either a b }
    

    So we have constructor FlipEither :: Either a b -> FlipEither b a that wraps an Either into our newtype with swapped type arguments. And we have dectructor unFlipEither :: FlipEither b a -> Either a b that unwraps it back. Now we can define a functor instance in FlipEither's last argument, which is actually Either's first argument:

    instance Functor (FlipEither b) where
        fmap f (FlipEither (Left x))  = FlipEither (Left (f x))
        fmap f (FlipEither (Right x)) = FlipEither (Right x)
    

    Notice that if we forget FlipEither for a while we get just the definition of Functor for Either, just with Left/Right swapped. And now, whenever we need a Functor instance in Either's first type argument, we can wrap the value into FlipEither and unwrap it afterward. For example:

    fmapE2 :: (a -> b) -> Either a c -> Either b c
    fmapE2 f = unFlipEither . fmap f . FlipEither
    

    Update: Have a look at Data.Bifunctor, of which Either and (,) are instances of. Each bifunctor has two arguments and is a functor in each of them. This is reflected in Bifunctor's methods first and second.

    The definition of Bifunctor of Either is very symetric:

    instance Bifunctor Either where
        bimap f _ (Left a)  = Left (f a)
        bimap _ g (Right b) = Right (g b)
    
        first  f = bimap f id
    
        second f = bimap id f
    

提交回复
热议问题