
On Fri, May 11, 2001 at 02:14:24PM +0200, Marcin 'Qrczak' Kowalczyk wrote:
On Fri, 11 May 2001, Lauri Alanko wrote:
Why? This makes composing and "subtyping" impossible:
instance (MonadTrans t, MonadState s m, Monad (t m)) => MonadState s (t m) where get = lift get put = lift . put
This instance is illegal anyway. One of types in the instance head must be a type constructor applied to something (type variables in Haskell 98, anything with -fglasgow-exts).
Ah. So it seems. Pardon. It works in Hugs, though.
Even if it was legal, it would overlap with instance Monad m => MonadState s (StateT s m)
Yep, but in hugs +o the latter overrides the first one. Which is quite convenient.
Also MonadReader and MonadWriter can't have such generic instances anyway because their methods have values of type 'm a' as arguments.
Oh? translift :: (MonadTrans t, Monad m, Monad (t m)) => (m a -> m b) -> t m a -> t m b translift f m = m >>= lift . f . return instance (MonadTrans t, MonadReader r m, Monad (t m)) => MonadReader r (t m) where ask = lift ask local = translift . local instance (MonadTrans t, MonadWriter w m, Monad (t m), Monoid w) => MonadWriter w (t m) where tell = lift . tell listen = translift listen pass = translift pass
OTOH without the fundep there are ambiguities. For example:
class ParsingState s where stateInput :: s -> String stateSkip :: Int -> s -> s
instance ParsingState String where ... instance ParsingState s => ParsingState (s, Pos) where ...
input :: (ParsingState s, MonadState s m) => m String -- Ambiguous without the fundep. input = gets stateInput
So it is, and why not? Is it inconceivable that m might actually have multiple ParsingStates, and thus you really have to specify which one you want to use to get the input? Lauri Alanko la@iki.fi