Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Tuple not have a Monad instance?

One thing I noticed was that Tuple does not have a Monad instance.

Tuple does however have an Applicative instance:

instance Monoid a => Applicative ((,) a)

Which already extremely heavily restricts what we can make the Monad instance be.

Lets look at the type signature we would get for join:

instance Monoid a => Monad ((,) a)

join :: Monad m => m (m a) -> m a

join :: Monoid a => (a, (a, b)) -> (a, b)

We can also look at the Monad laws:

join $ f <$> pure x == f x
join $ f <$> (mempty, x) == f x
join (mempty, f x) == f x
join (mempty, (a, b)) == (a, b)

join $ pure <$> x = x
join $ pure <$> (a, b) = (a, b)
join (a, (mempty, b)) = (a, b)

At this point we know that combining mempty and x in either way results in x. And the only type information we have about x is that it is a Monoid. So basically the only two implementations are:

join (a, (b, x)) = (a <> b, x)

and:

join (a, (b, x)) = (b <> a, x)

And the second one of those makes ap and <*> not the same.

So now we know that the only valid Monad instance for ((,) a) is:

instance Monoid a => Monad ((,) a) where
    (a, c) >>= f = let (b, c') = f c in (a <> b, c')

So why is that not currently the case?

like image 547
semicolon Avatar asked Jul 16 '16 20:07

semicolon


1 Answers

Well it seems like the answer to this question is that I just have to use ghc-8.0.1, which does give Tuple a Monad instance. Credit to @Michael for pointing this out.

like image 135
semicolon Avatar answered Nov 10 '22 02:11

semicolon