This is a wrapper to a couple of two objects of the same type
data Pair a = Pair a a deriving (Show)
--newtype Pair a = Pair (a,a) deriving (Show) -- not this
It seems to be easily made a functor, by having the mapping function act on both values,
instance Functor Pair where
fmap f (Pair a b) = Pair (f a) (f b)
and the functor laws seem to hold too, am I wrong? Ok, this instance seems pretty useless, but at least it looks intuitive to me: what else would I want to do, given a function and a wrapper to two values, instead of doing this?
We can also make it an applicative functor
instance Applicative Pair where
pure a = Pair a a
Pair f g <*> Pair x y = Pair (f x) (g y)
even though I've not checked if composition and interchange laws are verified (identity and homomorphism are). Like before, I see this instance a bit trivial but easy to look at: what else would I do, instead of this?
However, I don't see how it can be made a Monad
. (>>=)
's second arument should be a function which acts on one entity of the type given to the Monad
type constructor, right? In this case, however, Pair
contains two, possibly different, values. So there's a problem of choosing how a function, say, of type Int -> Pair Int
should act on the inside of, say, Pair 3 4
. I guess I could invented it, but having it adhere to the monad laws does not seem obvious to me. Plus it should be consistent with the above Functor
and Applicative
instances.
Is there an obvious reason why Pair
cannot be made a monad? Or maybe it can, and I'm just confused?