
On Fri, 2011-09-23 at 23:46 +0100, Duncan Coutts wrote:
On 23 September 2011 21:25, Maciej Marcin Piechotka
wrote: The problem of backward compatibility have been the main obstacle against adopting Functor f => (Pointed f =>?) => Applicative f => Monad f.
This proposition is to add following default instances[1]:
Sorry, I'm confused! The [1] link is about default superclass instances, not default signatures. As I understand it, default superclass instances are not implemented yet.
Ups. You're right.
I fully support the general aim and default superclass instances look like a very sensible way of addressing the problem. It's just not clear to me how the default signatures you're suggesting here get us closer to the goal.
Perhaps you can explain it a bit more. I suspect other people on this list don't quite get it either.
From example in link [2]. If we had:
class Functor f where fmap :: (a -> b) -> f a -> f b default fmap :: Applicative f => (a -> b) -> f a -> f b f `fmap` m = pure f <*> m (<$) :: a -> f b -> f a (<$) = fmap . const
class Functor f => Pointed f where point :: a -> f a default point :: Applicative f => a -> f a point = pure
class Pointed f => Applicative f where pure :: a -> f a default pure :: Monad f => a -> f a pure = return (<*>) :: f (a -> b) -> f a -> f b default (<*>) :: Monad f => f (a -> b) -> f a -> f b f <*> v = liftM2 ($) f v (*>) :: f a -> f b -> f b (*>) = liftA2 (const id) (<*) :: f a -> f b -> f a (<*) = liftA2 const
class Applicative f => Monad f where return :: a -> f a (>>=) :: f a -> (a -> f b) -> f b (>>) :: f a -> f b -> f b m >> k = m >>= const k
Then having:
data List a = List a (List a) | Empty
instance Monad List where return x = List x Empty Empty >>= _ = Empty List v vs >>= f = List (f v) (vs >>= f)
is sufficient to use (in current GHC) to use: test = Empty <*> List 1 Empty Hence adding default instances + fixing the hierarchy seems to be sufficient to have backward compatibility for instance declaration.
default fmap :: Applicative f => (a -> b) -> f a -> f b f `fmap` m = pure f <*> m default pure :: Monad f => a -> f a pure = return default (<*>) :: Monad f => f (a -> b) -> f a -> f b (<*>) = liftM2 ($)
Duncan
Regards