This module provides alternatives to the
allowing for constraints on the contained type (a restricted monad).
It makes use of associated datatypes (available in GHC 6.8).
data instance Constraints Set a = Ord a => SetConstraints instance Ord a => Suitable Set a where constraints _ = SetConstraints
You need to change
Set to your own type,
Ord a to your own
SetConstraints to some distinguished name (this name
will not normally be visible to users of your type)
Next you can make an instance of
RMonad and if appropriate
by defining the members in the usual way. When you need to make use of the
constraint on the contained type, you will need to get hold of the constraint
wrapped up in the
Constraints datatype. For example here are the instances
instance RMonad Set where return = Set.singleton s >>= f = let res = case constraints res of SetConstraints -> Set.fold (a s' -> Set.union (f a) s') Set.empty s in res fail _ = Set.empty
instance RMonadPlus Set where mzero = Set.empty mplus s1 s2 = let res = case constraints res of SetConstraints -> Set.union s1 s2 in res
Once you have made your type an instance of
RMonad, you can
use it in two ways.
Firstly, import this module directly and use the
so that do-syntax is rebound.
Secondly, use the wrapper type in Control.RMonad.AsMonad which supports
class Suitable m a where
|Suitable  a|
|Suitable IO a|
|Suitable Maybe a|
|Ord a => Suitable Set a|
|Suitable ((->) r) a|
|(Suitable m a, Suitable m [a]) => Suitable (ListT m) a|
|(Ord a, Suitable m a, Suitable m (Set a)) => Suitable (SetT m) a|
|Suitable m a => Suitable (ReaderT r m) a|
|(Suitable m a, Suitable m r) => Suitable (ContT r m) a|