{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE MultiParamTypeClasses #-}
module Control.FX.Monad.Except (
Except(..)
, runExcept
, Context(..)
, Input(..)
, Output(..)
) where
import Data.Typeable (Typeable)
import Control.FX.EqIn
import Control.FX.Functor
import Control.FX.Monad.Class
data Except
(mark :: * -> *)
(e :: *)
(a :: *)
= Except e
| Accept a
deriving (Eq, Show, Typeable)
instance
( MonadIdentity mark
) => Functor (Except mark e)
where
fmap
:: (a -> b)
-> Except mark e a
-> Except mark e b
fmap f x = case x of
Except e -> Except e
Accept a -> Accept (f a)
instance
( MonadIdentity mark
) => Applicative (Except mark e)
where
pure
:: a
-> Except mark e a
pure = Accept
(<*>)
:: Except mark e (a -> b)
-> Except mark e a
-> Except mark e b
f' <*> x' =
case f' of
Except e -> Except e
Accept f -> case x' of
Except e -> Except e
Accept x -> Accept (f x)
instance
( MonadIdentity mark
) => Monad (Except mark e)
where
return
:: a
-> Except mark e a
return = Accept
(>>=)
:: Except mark e a
-> (a -> Except mark e b)
-> Except mark e b
x' >>= f =
case x' of
Except e -> Except e
Accept x -> f x
instance
( MonadIdentity mark
) => Commutant (Except mark e)
where
commute
:: ( Applicative f )
=> Except mark e (f a)
-> f (Except mark e a)
commute x = case x of
Except e -> pure (Except e)
Accept m -> Accept <$> m
instance
( MonadIdentity mark
) => Bifunctor (Except mark)
where
bimap1
:: (e -> c)
-> Except mark e a
-> Except mark c a
bimap1 f x = case x of
Except e -> Except (f e)
Accept a -> Accept a
bimap2
:: (a -> c)
-> Except mark e a
-> Except mark e c
bimap2 f x = case x of
Except e -> Except e
Accept a -> Accept (f a)
instance
( MonadIdentity mark
) => Central (Except mark e)
instance
( Eq e
) => EqIn (Except mark e)
where
newtype Context (Except mark e)
= ExceptCtx
{ unExceptCtx :: mark ()
} deriving (Typeable)
eqIn
:: (Eq a)
=> Context (Except mark e)
-> Except mark e a
-> Except mark e a
-> Bool
eqIn _ = (==)
deriving instance
( Eq (mark ())
) => Eq (Context (Except mark e))
deriving instance
( Show (mark ())
) => Show (Context (Except mark e))
instance
( MonadIdentity mark
) => RunMonad (Except mark e)
where
newtype Input (Except mark e)
= ExceptIn
{ unExceptIn :: mark ()
} deriving (Typeable)
newtype Output (Except mark e) a
= ExceptOut
{ unExceptOut :: Except mark e a
} deriving (Typeable)
run
:: Input (Except mark e)
-> Except mark e a
-> Output (Except mark e) a
run _ = ExceptOut
runExcept
:: ( MonadIdentity mark )
=> Except mark e a
-> Except mark e a
runExcept = id
deriving instance
( Eq (mark ())
) => Eq (Input (Except mark e))
deriving instance
( Show (mark ())
) => Show (Input (Except mark e))
deriving instance
( Eq e, Eq a
) => Eq (Output (Except mark e) a)
deriving instance
( Show e, Show a
) => Show (Output (Except mark e) a)
instance
( MonadIdentity mark
) => MonadExcept mark e (Except mark e)
where
throw
:: mark e
-> Except mark e a
throw = Except . unwrap
catch
:: Except mark e a
-> (mark e -> Except mark e a)
-> Except mark e a
catch x h = case x of
Accept a -> Accept a
Except e -> h (pure e)