-- | A simple result type. Similar to the 'Either' type, but tuned for results with an error type.
module ConditionalRestriction.Result
  ( Result (..),
    fromResult,
  )
where

import Data.Bifunctor (Bifunctor, bimap)

-- | The 'Result' type consists of an error type @e@ and a success type @a@.
data Result e a
  = Err e
  | Ok a
  deriving (Result e a -> Result e a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall e a. (Eq e, Eq a) => Result e a -> Result e a -> Bool
/= :: Result e a -> Result e a -> Bool
$c/= :: forall e a. (Eq e, Eq a) => Result e a -> Result e a -> Bool
== :: Result e a -> Result e a -> Bool
$c== :: forall e a. (Eq e, Eq a) => Result e a -> Result e a -> Bool
Eq, Int -> Result e a -> ShowS
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall e a. (Show e, Show a) => Int -> Result e a -> ShowS
forall e a. (Show e, Show a) => [Result e a] -> ShowS
forall e a. (Show e, Show a) => Result e a -> String
showList :: [Result e a] -> ShowS
$cshowList :: forall e a. (Show e, Show a) => [Result e a] -> ShowS
show :: Result e a -> String
$cshow :: forall e a. (Show e, Show a) => Result e a -> String
showsPrec :: Int -> Result e a -> ShowS
$cshowsPrec :: forall e a. (Show e, Show a) => Int -> Result e a -> ShowS
Show)

instance Functor (Result e) where
  fmap :: forall a b. (a -> b) -> Result e a -> Result e b
fmap a -> b
f (Ok a
a) = forall e a. a -> Result e a
Ok (a -> b
f a
a)
  fmap a -> b
_ (Err e
e) = forall e a. e -> Result e a
Err e
e

instance Bifunctor Result where
  bimap :: forall a b c d. (a -> b) -> (c -> d) -> Result a c -> Result b d
bimap a -> b
f c -> d
_ (Err a
e) = forall e a. e -> Result e a
Err forall a b. (a -> b) -> a -> b
$ a -> b
f a
e
  bimap a -> b
_ c -> d
f (Ok c
x) = forall e a. a -> Result e a
Ok forall a b. (a -> b) -> a -> b
$ c -> d
f c
x

instance Applicative (Result e) where
  pure :: forall a. a -> Result e a
pure = forall e a. a -> Result e a
Ok
  (Ok a -> b
f) <*> :: forall a b. Result e (a -> b) -> Result e a -> Result e b
<*> (Ok a
x) = forall e a. a -> Result e a
Ok (a -> b
f a
x)
  (Err e
f) <*> Result e a
_ = forall e a. e -> Result e a
Err e
f
  Result e (a -> b)
_ <*> (Err e
x) = forall e a. e -> Result e a
Err e
x

instance Monad (Result e) where
  return :: forall a. a -> Result e a
return = forall (f :: * -> *) a. Applicative f => a -> f a
pure
  (Ok a
x) >>= :: forall a b. Result e a -> (a -> Result e b) -> Result e b
>>= a -> Result e b
f = a -> Result e b
f a
x
  (Err e
x) >>= a -> Result e b
_ = forall e a. e -> Result e a
Err e
x

-- | 'Result' equivalent to 'Data.Maybe.fromMaybe'.
fromResult :: a -> Result e a -> a
fromResult :: forall a e. a -> Result e a -> a
fromResult a
_ (Ok a
x) = a
x
fromResult a
x (Err e
_) = a
x