module Argo.Result where

import qualified Control.Applicative as Applicative

data Result a
    = Failure String
    | Success a
    deriving (Result a -> Result a -> Bool
(Result a -> Result a -> Bool)
-> (Result a -> Result a -> Bool) -> Eq (Result a)
forall a. Eq a => Result a -> Result a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Result a -> Result a -> Bool
$c/= :: forall a. Eq a => Result a -> Result a -> Bool
== :: Result a -> Result a -> Bool
$c== :: forall a. Eq a => Result a -> Result a -> Bool
Eq, Int -> Result a -> ShowS
[Result a] -> ShowS
Result a -> String
(Int -> Result a -> ShowS)
-> (Result a -> String) -> ([Result a] -> ShowS) -> Show (Result a)
forall a. Show a => Int -> Result a -> ShowS
forall a. Show a => [Result a] -> ShowS
forall a. Show a => Result a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Result a] -> ShowS
$cshowList :: forall a. Show a => [Result a] -> ShowS
show :: Result a -> String
$cshow :: forall a. Show a => Result a -> String
showsPrec :: Int -> Result a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> Result a -> ShowS
Show)

instance Functor Result where
    fmap :: (a -> b) -> Result a -> Result b
fmap a -> b
f Result a
r = case Result a
r of
        Failure String
e -> String -> Result b
forall a. String -> Result a
Failure String
e
        Success a
x -> b -> Result b
forall a. a -> Result a
Success (b -> Result b) -> b -> Result b
forall a b. (a -> b) -> a -> b
$ a -> b
f a
x

instance Applicative Result where
    pure :: a -> Result a
pure = a -> Result a
forall a. a -> Result a
Success
    Result (a -> b)
rf <*> :: Result (a -> b) -> Result a -> Result b
<*> Result a
rx = case (Result (a -> b)
rf, Result a
rx) of
        (Failure String
e, Result a
_) -> String -> Result b
forall a. String -> Result a
Failure String
e
        (Result (a -> b)
_, Failure String
e) -> String -> Result b
forall a. String -> Result a
Failure String
e
        (Success a -> b
f, Success a
x) -> b -> Result b
forall a. a -> Result a
Success (b -> Result b) -> b -> Result b
forall a b. (a -> b) -> a -> b
$ a -> b
f a
x

instance Monad Result where
    Result a
r >>= :: Result a -> (a -> Result b) -> Result b
>>= a -> Result b
f = case Result a
r of
        Failure String
e -> String -> Result b
forall a. String -> Result a
Failure String
e
        Success a
x -> a -> Result b
f a
x

instance MonadFail Result where
    fail :: String -> Result a
fail = String -> Result a
forall a. String -> Result a
Failure

instance Applicative.Alternative Result where
    empty :: Result a
empty = String -> Result a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"empty"
    Result a
rx <|> :: Result a -> Result a -> Result a
<|> Result a
ry = case Result a
rx of
        Failure String
_ -> Result a
ry
        Success a
_ -> Result a
rx