Defining instance needs allow-undecidable-instance?

Hi, folks. I've got a working class and instances thereof. I would now like to change the class such that error behaviour is specified by MonadError, for the moment throwing String errors. When I try to add MonadError into the types I eventually hit the requirement for allow-undecidable-instances. Is there some way I can I avoid having to use this extension? My starting point consists of: class (Num i, Bounded i, Monad m) => MonadSource i m | m -> i where ... newtype SourceT i m a = SourceT (StateT (Store i) m a) deriving (Functor, Monad, MonadIO, MonadTrans) instance (Num i, Bounded i, Monad m) => MonadSource i (SourceT i m) where ... I changed it to: class (Num i, Bounded i, Monad m, MonadError String m) => MonadSource i m | m -> i where .... newtype SourceT i m a = SourceT (StateT (Store i) m a) deriving (Functor, Monad, MonadIO, MonadTrans, MonadError e) instance (Num i, Bounded i, Monad m, MonadError String m) => MonadSource i (SourceT i m) where ... Thanks Daniel

On Tuesday 28 March 2006 11:12, Daniel McAllansmith wrote:
Hi, folks.
I've got a working class and instances thereof. I would now like to change the class such that error behaviour is specified by MonadError, for the moment throwing String errors. When I try to add MonadError into the types I eventually hit the requirement for allow-undecidable-instances. Is there some way I can I avoid having to use this extension?
I've received a link[1] off-list to a patch to GHC changing this behaviour, so it looks like in the future I'll be able to remove the allow-undecidable-instances flag and rely on just glasgow-exts.
instance (Num i, Bounded i, Monad m, MonadError String m) => MonadSource i (SourceT i m) where ...
That aside, is what I have done, including a type in the context, considered an acceptable solution for this sort of problem? Cheers Daniel [1] http://article.gmane.org/gmane.comp.lang.haskell.cvs.ghc/13500

Daniel McAllansmith wrote:
When I try to add MonadError into the types I eventually hit the requirement for allow-undecidable-instances. Is there some way I can I avoid having to use this extension?
class (Num i, Bounded i, Monad m, MonadError String m) => MonadSource i m | m -> i where
The constraint |MonadError String m| that shows up in the class (and hence, eventually) instance context contains a type constant String. Such constraints indeed require 'allow-undecidable-instances'. It is possible to get around such requirement in some cases, by `shifting the blame (that is, the constraint)':
{-# OPTIONS -fglasgow-exts #-}
import Control.Monad import Control.Monad.Identity import Control.Monad.Trans import Control.Monad.Error import Control.Monad.State
class (Num i, Bounded i, Monad m) => MonadSource i m | m -> i where foo :: MonadError String m => m i
newtype SourceT i m a = SourceT (StateT i m a) deriving (Functor, Monad, MonadIO, MonadTrans, MonadError String)
runSourceT (SourceT m) = runStateT m 10
instance (Num i, Bounded i, Monad m) => MonadSource i (SourceT i m) where foo = if True then return 1 else throwError "error"
test :: Either String (Int,Int) = runIdentity . runErrorT . runSourceT $ foo
participants (2)
-
Daniel McAllansmith
-
oleg@pobox.com