# Correct definition of a new type

I am wondering why the following is the correct implementation of the pair type. In particular, why `Pair b a`

not `Pair a b`

?

```
newtype Pair b a = Pair { getPair :: (a,b) }
```

To clarify, `Pair a b`

doesn't work for the following:

```
instance Functor (Pair c) where
fmap f (Pair (x,y)) = Pair (f x, y)
```

and I don't understand why.

In addition to a lot of great answers below, I found ghci helpful:

```
*Main> newtype Pair b a = Pair (a, b) deriving (Show, Eq)
*Main> :t Pair(True, "cat")
Pair(True, "cat") :: Pair [Char] Bool
*Main> newtype Pair a b = Pair (a, b) deriving (Show, Eq)
*Main> :t Pair(True, "cat")
Pair(True, "cat") :: Pair Bool [Char]
```

source to share

You are talking about the definition in LYAH :

```
newtype Pair b a = Pair { getPair :: (a,b) }
```

Pay attention to the paragraph that precedes it (emphasis mine):

It turns out that writing an instance for this is pretty heavy. With,

`Maybe`

we'll just say that a Functor instance can be, because since only type constructors that take exactly one parameter can be made a Functor instance.But it looks like there is no way to do something like this with`(a,b)`

so that the type parameter a turns out to be the one that changes as we use`fmap`

. To work around this, we can newtype our tuple so that the second type parameter represents the type of the first component in the tuple:

So, in this case, we want the type of the first element of the (main) pair to be the last type in the type constructor `Pair`

. Finally, we want to use `fmap`

for the first argument in LYAH:

```
-- b
-- |
-- v a isn't here…
instance Functor (Pair c) where
-- but here!
--fmap :: (a -> x) -> Pair c a -> Pair c x
fmap f (Pair (x,y)) = Pair (f x, y)
```

You can, of course, change the definition to `newtype Pair b a = Pair { getPair :: (a,b) }`

. But what happens in this case?

```
-- a
-- |
-- v b isn't here…
instance Functor (Pair c) where
-- but here! v---- c ----v--------------------------+
--fmap :: (b -> x) -> Pair c b -> Pair c x |
fmap f (Pair (x,y)) = Pair (f x, y) -- |
-- ^^^ uh-oh - that doesn't seem right-+
```

Remember your base type is now `(a,b)`

. However, your `Functor`

instance is `a`

now fixed, but you are trying to apply to it `fmap`

. This does not work. Instead, you should use `fmap`

for the second entry, which matches `b`

from the type constructor `Pair a b`

:

```
-- a
-- |
-- v b isn't here…
instance Functor (Pair c) where
-- but here!
--fmap :: (b -> x) -> Pair c b -> Pair c x
fmap f (Pair (x,y)) = Pair (x, f y)
-- ^^^ everything fine now.
```

But at this point we are back to the original instance `(a,b)`

.

source to share