module Control.Exceptional where
import Control.Applicative
data Exceptional x
= Failure String
| Success x
deriving (Eq,Show,Read)
instance Functor Exceptional where
fmap f (Success a) = Success (f a)
fmap _ (Failure s) = Failure s
instance Applicative Exceptional where
pure = Success
Success f <*> Success x = Success (f x)
Failure s <*> _ = Failure s
_ <*> Failure s = Failure s
instance Alternative Exceptional where
Success a <|> _ = Success a
_ <|> Failure s = Failure s
instance Monad Exceptional where
(>>=) (Success x) f = f x
(>>=) (Failure s) _ = Failure s
fail = Failure
return = pure
runExceptional :: Monad m => Exceptional x -> m x
runExceptional (Failure s) = fail s
runExceptional (Success s) = pure s