module Control.Monad.Constrained.Ap
(Monad(..)
,MonadFail(..)
,return
,ifThenElse
,(>>))
where
import Control.Monad.Constrained (Ap (..), liftAp, lower)
import qualified Control.Monad.Constrained as Constrained
import GHC.Exts
import qualified Control.Monad
import Prelude hiding (Monad (..))
import qualified Prelude
import Control.Monad.Trans.Cont (ContT)
import Control.Monad.Trans.Except (ExceptT(..))
import Control.Monad.Trans.Identity (IdentityT (..))
import Control.Monad.Trans.Maybe (MaybeT(..))
import Control.Monad.Trans.Reader (ReaderT (..))
import Control.Monad.Trans.State (StateT)
import qualified Control.Monad.Trans.State.Strict as Strict (StateT)
import Data.Functor.Identity (Identity)
import Data.Sequence (Seq)
class Applicative f =>
Monad f where
type Suitable f a :: Constraint
infixl 1 >>=
(>>=)
:: (Suitable f a, Suitable f b)
=> f a -> (a -> f b) -> f b
join
:: Suitable f a
=> f (f a) -> f a
class Monad f => MonadFail f where
fail :: Suitable f a => String -> f a
instance Constrained.Monad f =>
Monad (Ap f) where
type Suitable (Ap f) a = Constrained.Suitable f a
(>>=) ap f = liftAp (lower ap Constrained.>>= (lower . f))
join = liftAp . go id . fmap lower
where
go
:: forall a f b.
(Constrained.Suitable f b, Constrained.Monad f)
=> (a -> f b) -> Ap f a -> f b
go c (Pure x) = c x
go f (Ap xs x) =
go
(\c ->
x Constrained.>>= (f . c))
xs
return :: Applicative f => a -> f a
return = pure
ifThenElse :: Bool -> a -> a -> a
ifThenElse True t _ = t
ifThenElse False _ f = f
infixl 1 >>
(>>)
:: Applicative f
=> f a -> f b -> f b
(>>) = (*>)
instance Monad [] where
type Suitable [] a = ()
(>>=) = (Prelude.>>=)
join = Control.Monad.join
instance MonadFail [] where
fail _ = []
instance Monad Maybe where
type Suitable Maybe a = ()
(>>=) = (Prelude.>>=)
join = Control.Monad.join
instance MonadFail Maybe where
fail _ = Nothing
instance Monad IO where
type Suitable IO a = ()
(>>=) = (Prelude.>>=)
join = Control.Monad.join
instance MonadFail IO where
fail = Prelude.fail
instance Monad Identity where
type Suitable Identity a = ()
(>>=) = (Prelude.>>=)
join = Control.Monad.join
instance Monad (Either e) where
type Suitable (Either e) a = ()
(>>=) = (Prelude.>>=)
join = Control.Monad.join
instance IsString a =>
MonadFail (Either a) where
fail = Left . fromString
instance Monoid m =>
Monad ((,) m) where
type Suitable ((,) m) a = ()
(>>=) = (Prelude.>>=)
join = Control.Monad.join
instance Monad Seq where
type Suitable Seq a = ()
(>>=) = (Prelude.>>=)
join = Control.Monad.join
instance MonadFail Seq where
fail _ = Constrained.empty
instance Monad ((->) b) where
type Suitable ((->) b) a = ()
(>>=) = (Prelude.>>=)
join = Control.Monad.join
instance Monad (ContT r m) where
type Suitable (ContT r m) a = ()
(>>=) = (Prelude.>>=)
join = Control.Monad.join
instance Prelude.Monad m =>
Monad (Strict.StateT s m) where
type Suitable (Strict.StateT s m) a = ()
(>>=) = (Prelude.>>=)
join = Control.Monad.join
instance Prelude.Monad m =>
Monad (StateT s m) where
type Suitable (StateT s m) a = ()
(>>=) = (Prelude.>>=)
join = Control.Monad.join
instance Monad m =>
Monad (ReaderT s m) where
type Suitable (ReaderT s m) a = Suitable m a
m >>= k =
ReaderT $
\r -> do
a <- runReaderT m r
runReaderT (k a) r
join (ReaderT x) =
ReaderT
(\r ->
join (flip runReaderT r <$> x r))
instance MonadFail m =>
MonadFail (ReaderT r m) where
fail = ReaderT . const . fail
instance Prelude.Monad m =>
Monad (MaybeT m) where
type Suitable (MaybeT m) a = ()
(>>=) = (Prelude.>>=)
join = Control.Monad.join
instance Prelude.Monad m =>
MonadFail (MaybeT m) where
fail _ = Control.Monad.mzero
instance Prelude.Monad m =>
Monad (ExceptT e m) where
type Suitable (ExceptT e m) a = ()
(>>=) = (Prelude.>>=)
join = Control.Monad.join
instance (Prelude.Monad m, IsString e) => MonadFail (ExceptT e m) where
fail = ExceptT . pure . Left . fromString
instance Monad m =>
Monad (IdentityT m) where
type Suitable (IdentityT m) a = Suitable m a
(>>=) =
(coerce :: (f a -> (a -> f b) -> f b) -> IdentityT f a -> (a -> IdentityT f b) -> IdentityT f b)
(>>=)
join (IdentityT x) = IdentityT (join (fmap runIdentityT x))
instance MonadFail m =>
MonadFail (IdentityT m) where
fail = IdentityT . fail