
Hi folks I just tripped over the "Contexts differ in length" error message. I know it's not a new problem, but I thought I'd enquire as to its status. For those of you who haven't seen it, here's an example, contrived but compact.
data Thing = Val Int | Grok Thing (Maybe Int -> Int)
eval :: Monad m => Thing -> m Int eval (Val i) = return i eval (Grok t f) = return (f (eval t))
My eval function compiles ok. See? The recursive call to eval targets the Maybe monad, so I get *Mmm> eval (Grok (Val 5) (maybe 0 (1 +))) :: Maybe Int Just 6 However, when I try to decompose eval as a pair of mutually recursive functions, namely
foo :: Monad m => Thing -> m Int foo (Val i) = return i foo (Grok t f) = return (goo t f)
goo :: Thing -> (Maybe Int -> Int) -> Int goo t f = f (foo t)
I get Mmm.lhs:15:1: Contexts differ in length When matching the contexts of the signatures for foo :: forall (m :: * -> *). (Monad m) => Thing -> m Int goo :: Thing -> (Maybe Int -> Int) -> Int The signature contexts in a mutually recursive group should all be identical Poking about on the web, I got the impression that this was a known infelicity in ghc 6.4 (which I'm using), due to be ironed out. However, an early-adopting colleague with 6.6 alleges that foo-goo is still poisonous. I'm wondering what the story is. I mean, is there some nasty problem lurking here which prevents the lifting of this peculiar restriction? I'm not in a panic about this. I have a workaround for the problem as I encountered it in practice. Mind you, it's the sort of thing that's likely to happen more often, the more you localise the effects you tend to use. In the above, goo doesn't throw exceptions; rather, because goo has a handler, it can offer a /local/ exception-throwing capability to foo. Curious Conor