# [ACCEPTED]-Understanding how Either is an instance of Functor-either

Score: 24

This is right. There is also another quite 8 important reason for this behavior: You 7 can think of `Either a b` as a computation, that may 6 succeed and return `b` or fail with an error 5 message `a`. (This is also, how the monad instance 4 works). So it's only natural, that the functor 3 instance won't touch the `Left` values, since 2 you want to map over the computation, if 1 it fails, there's nothing to manipulate.

Score: 14

Your account is right of course. Maybe 20 the reason why we have a difficulty with 19 instances like this is that we are really 18 defining infinitely many functor instances 17 at once -- one for each possible `Left` type. But 16 a Functor instance is a systematic way of 15 operating on the infinitely many types 14 in the system. So we are defining infinitely 13 many ways of systematically operating on 12 the infinitely many types in the system. The 11 instance involves generality in two ways.

If 10 you take it by stages, though, maybe it's 9 not so strange. The first of these types 8 is a longwinded version of `Maybe` using the unit 7 type `()` and its only legitimate value `()`:

``````data MightBe b     = Nope ()    | Yep b
data UnlessError b = Bad String | Good b
data ElseInt b     = Else Int   | Value b
``````

Here 6 we might get tired and make an abstraction:

``````data Unless a b    = Mere a     | Genuine b
``````

Now 5 we make our Functor instances, unproblematically, the 4 first looking a lot like the instance for 3 `Maybe`:

``````instance Functor MightBe where
fmap f (Nope ()) = Nope ()   -- compare with Nothing
fmap f (Yep x)   = Yep (f x) -- compare with Just (f x)

instance Functor UnlessError where
fmap f (Good x)  = Good (f x)

instance Functor ElseInt where
fmap f (Else n) = Else n
fmap f (Value b) = Value (f b)
``````

But, again, why bother, let's make the 2 abstraction:

``````instance Functor (Unless a) where
fmap f (Mere a) = Mere a
fmap f (Genuine x) = Genuine (f x)
``````

The `Mere a` terms aren't touched, as 1 the `()`, `String` and `Int` values weren't touched.

Score: 5

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

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

So we have constructor `FlipEither :: Either a b -> FlipEither b a` that wraps 14 an `Either` into our `newtype` with swapped type arguments. And 13 we have dectructor `unFlipEither :: FlipEither b a -> Either a b` that unwraps it back. Now 12 we can define a functor instance in `FlipEither`'s last 11 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 10 that if we forget `FlipEither` for a while we get just 9 the definition of `Functor` for `Either`, just with `Left`/`Right` swapped. And 8 now, whenever we need a `Functor` instance in `Either`'s 7 first type argument, we can wrap the value 6 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 5 a look at Data.Bifunctor, of which `Either` and `(,)` are instances 4 of. Each bifunctor has two arguments and is a functor 3 in each of them. This is reflected in `Bifunctor`'s 2 methods `first` and `second`.

The definition of `Bifunctor` of `Either` is 1 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
``````
Score: 1

Now, I'm trying to understand why the implementation 16 maps in the case of a Right value constructor, but 15 doesn't in the case of a Left?

Plug in 14 here and it might make sense.

Assume a 13 = String (an error message) You apply Either 12 a to an Float.

So you have an f: Float 11 -> Integer say for example roundoff.

(Either 10 String) (Float) = Either String Float.

now 9 (fmap f):: Either String Float -> Either 8 String Int So what are you going to do with 7 f? f doesn't have a clue what to do with 6 strings so you can't do anything there. That 5 is obviously the only thing you can act on are the 4 right values while leaving the left values 3 unchanged.

In other words Either a is a 2 functor because there is such an obvious 1 fmap given by:

• for Right values apply f
• for Left values do nothing

More Related questions