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?
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.