
Henning: When a computation fails, there's no value to tie the recursive knot over. And in those cases, mfix is supposed to produce bottom. There's actually even a theorem showing that the mfix as defined satisfies all the required axioms of value-recursion if the underlying monad's mfix does (Page 54, Proposition 4.9.1 of https://sites.google.com/site/leventerkok/erkok-thesis.pdf) -Levent. On Tue, Aug 12, 2014 at 2:13 AM, Henning Thielemann < schlepptop@henning-thielemann.de> wrote:
I propose to remove the MonadFix instance for the ExceptT transformer, because it gives the illusion that it can handle exceptions, which it cannot.
The current implementation is:
instance (MonadFix m) => MonadFix (ExceptT e m) where mfix f = ExceptT $ mfix $ \ a -> runExceptT $ f $ case a of Right x -> x Left _ -> error "mfix ExceptT: Left"
You see, that it cannot handle the exception case. Whenever someone needs an mfix on ExceptT I strongly suggest that he first handles the exception, thus turning (ExceptT e m a) into plain (m a) and then calls 'mfix' only on (m a).
I further propose to declare the MonadFix instance as non-implementable in a way suggested in [1]:
class NoMonadFix m where
instance (NoMonadFix m) => MonadFix (ExceptT e m) where mfix = error "unimplementable"
where no instance of NoMonadFix exist and NoMonadFix is not exported. Whenever someone tries to call 'mfix' on 'ExceptT e m' he will get the type error, that a NoMonadFix instance on 'm' is missing and he will not be able to add it.
[1] http://ghc.haskell.org/trac/ghc/ticket/9334#comment:9 _______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries