module Success.Impure
(
Success(..),
run,
nothing, failure, success,
)
where
import Prelude
import Control.Applicative
import Control.Monad
import qualified Success.Pure
newtype Success a m b =
Success (m (Success.Pure.Success a b))
deriving (Functor)
instance Applicative m => Applicative (Success e m) where
pure a =
Success (pure (Success.Pure.success a))
(<*>) (Success m1) (Success m2) =
Success ((liftA2 . liftA2) ($) m1 m2)
instance Applicative m => Alternative (Success e m) where
empty =
Success (pure Success.Pure.nothing)
(<|>) (Success m1) (Success m2) =
Success (liftA2 (<|>) m1 m2)
instance Monad m => Monad (Success e m) where
return =
pure
(>>=) m1 m2' =
Success (run m1 >>= m2 . Success.Pure.asEither)
where
m2 =
\case
Left Nothing -> pure Success.Pure.nothing
Left (Just e) -> pure (Success.Pure.failure e)
Right x -> run (m2' x)
instance (Applicative m, Monad m) => MonadPlus (Success e m) where
mzero =
empty
mplus =
(<|>)
run :: Success e m a -> m (Success.Pure.Success e a)
run (Success m) =
m
nothing :: Applicative m => Success e m a
nothing =
Success (pure Success.Pure.nothing)
failure :: Applicative m => e -> Success e m a
failure details =
Success (pure (Success.Pure.failure details))
success :: Applicative m => a -> Success e m a
success value =
Success (pure (Success.Pure.success value))