Defining instance needs allow-undecidable-instance?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Defining instance needs allow-undecidable-instance?

Daniel McAllansmith
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
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Defining instance needs allow-undecidable-instance?

Daniel McAllansmith
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
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Defining instance needs allow-undecidable-instance?

oleg-7
In reply to this post by Daniel McAllansmith

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
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe