This module provides an alternative RMonad
and RMonadPlus
type class that
allows for constraints on the contained type (a restricted monad)
It makes use of associated datatypes (available in GHC 6.8).
To make your own type an instance of Monad
, first define
the Suitable
type class for it. For example,
instance Ord a => Suitable Set a where data Constraints Set a = Ord a => SetConstraints constraints _ = SetConstraints
You need to change Set
to your own type, Ord a
to your own
constraints, and 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 RMonadPlus
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
for Set
:
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 NoImplicitPrelude
extension
so that do-syntax is rebound.
Secondly, use the wrapper type in Control.RMonad.AsMonad which supports
the normal Monad
operations.
Documentation
class Suitable m a whereSource
data Constraints m a Source
constraints :: m a -> Constraints m aSource
class RMonad m => RMonadPlus m whereSource