Search code examples
haskellfunctor

How to write the Functor instance for this type?


I'm struggling with an exercise from Haskell Book (Chapter 16. Functor). Given the following, it expects me to define fmap:

{-# LANGUAGE FlexibleInstances #-}

newtype Flip f a b = 
   Flip (f b a) 
   deriving (Eq, Show)

newtype K a b = 
  K a

instance Functor (Flip K a) where
   fmap = undefined

In a previous exercise I've already done the following:

 data K a b =
   K a

 instance Functor (K a) where
   fmap f (K x) = K x

But for this Flip a b, I can't even understand how to get started, e.g. how to continue fmap f Flip ....

I thought maybe before doing that I should also write a functor for the newtype K a b, similar to what I did data K a b:

instance Functor (K a) where
  fmap f (K x) = K x

But I can't understand how to proceed to the Functor instance for Flip f a b.

Any ideas, hints?


Solution

  • Let's have a look at your solution:

    instance Functor (Flip K a) where
      fmap f (Flip (K a)) = Flip (K (f b))
    

    What does Flip (K a) actually mean?

    K is the constant functor, which you implemented correctly. It disregards the function f and always returns K a. But what actually happens behind the scenes is that the value K a b is transformed into K a c. Even though the function f was disregarded, the second type of K changed according to the type of f.

    Now if we Flip K, we simply turn around the arguments:

    Flip (K a b) == K b a
    

    Instead of having a constant value and ignoring the function, we have a changing value and a constant "ignored" type. Looking at the implementation with explicit type signatures we get:

    instance Functor (Flip K a) where
      fmap :: (b -> c) -> Flip K a b -> Flip K a c -- or:
      fmap :: (b -> c) -> K b a -> K c a
      fmap f (Flip (K a)) = Flip (K (f b))
    

    As you already concluded, the only possible implementation is the one above.

    You can actually see the use cases of a Constant functor in this question.