About this code from LearnYouaHaskell:
newtype Pair b a = Pair {getPair :: (a,b)}
instance Functor (Pair c) where
fmap f (Pair (x, y)) = Pair (f x, y)
I understand that the first line creates a new data type from tuple. However, why does the order of arguments switched from Pair b a
to getPair :: (a,b)
? If I switch one of the order, then I get an error due to pattern matching in the definition of fmap
.
The Functor
class requires a single type argument, while the Pair
type has two. The instance definition for Pair
:
instance Functor (Pair c) where ...
fixes the first type argument, which corresponds to the second element of the tuple. This means that fmap
transforms the first element of the tuple. If the type arguments for Pair
were in the other order, you would transform the second tuple element instead and the definition would have to change to:
fmap f (Pair (x, y)) = Pair (x, f y)
note the built-in definition for Functor
on pairs already behaves this way e.g.
import Data.Functor
fmap (+1) ("first", 3)