This post was really intended to be just a comment to another blog post, but since I wanted to include some code it turned out to be better to write a little post myself.
sigfpe has a nice post about
Parameterized Monads, which pop up naturally ones you've done a bit of monadic programming. He argues that the ordinary Monad concept we have in Haskell is the wrong one, Paramterized Monads fall out so naturally that they ought to be the default. He then goes on to say "At the very least, do-notation needs to be adapted to support ParameterisedMonad." But GHC already supports do-notation for Parameterized Monads! Here's a proof:
> {-# LANGUAGE NoImplicitPrelude #-}
> module PMonad where
> import Prelude (fromInteger,(+),(*),show)
> class PMonad m where
> return :: a -> m s s a
> (>>=) :: m s1 s a -> (a -> m s s2 b) -> m s1 s2 b
> (>>) :: m s1 s2 a -> m s2 s3 b -> m s1 s3 b
> fail :: m s1 s2 a
> data State s1 s2 a = State { runState :: s1 -> (a,s2) }
> instance PMonad State where
> return a = State (\s -> (a,s))
> f >>= m = State (\s1 ->
> case runState f s1 of
> (a,s2) -> runState (m a) s2)
> m1 >> m2 = m1 >>= \_ -> m2
> fail = fail
> get = State (\s -> (s,s))
> put s = State (\_ -> ((),s))
> test1 = do x <- return 1
> y <- return 2
> z <- get
> put (x+y*z)
> return z
> go1 = runState test1 10
> test2 = do x <- return 1
> y <- return 2
> z <- get
> put (show (x+y*z))
> return z
> go2 = runState test2 10
[1 of 1] Compiling PMonad ( PMonad.hs, interpreted )
Ok, modules loaded: PMonad.
*PMonad> go2
(10,"21")
And there you go. It's the NoImplicitPrelude that does the trick.
4 comments:
They support it now, but back then it was an open bug report. =)
Woops, by the time of sigfpe's article it was fixed. At the time I wrote mine it wasn't ;)
Luckily we managed to bother SPJ so much that he fixed it some time ago :)
@Edward Kmett: Hm, it looks as if this behavior was (meeant to be) included in 6.8.2, at least ( http://www.haskell.org/ghc/docs/6.8.2/html/users_guide/syntax-extns.html#rebindable-syntax ).
Post a Comment