module Data.Result where
import Prologue
import Control.Monad.Poly
import Control.Applicative.Poly
import Data.Maybe (fromJust)
data Ok a = Ok a deriving (Show, Functor, Foldable, Traversable)
data Error e a = Error deriving (Show)
fromOk :: Ok a -> a
fromOk (Ok a) = a
class MaybeResult m where maybeResult :: m a -> Maybe a
instance MaybeResult Ok where maybeResult = Just ∘ unwrap'
instance MaybeResult (Error e) where maybeResult = const Nothing
unsafeFromResult :: MaybeResult m => m a -> a
unsafeFromResult = fromJust ∘ maybeResult
class IfOk m where ifOk :: m a -> (a -> b) -> b -> b
instance IfOk Ok where ifOk (Ok a) f _ = f a
instance IfOk (Error e) where ifOk _ _ e = e
instance Applicative Ok where pure = Ok
Ok f <*> Ok a = Ok $ f a
instance Monad Ok where return = Ok
Ok a >>= f = f a
instance Functor (Error e) where fmap f e = Error
instance Applicative (Error e) where pure _ = Error
_ <*> _ = Error
instance Monad (Error e) where return _ = Error
_ >>= f = Error
instance Coated Ok
type instance Unlayered (Ok a) = a
instance Layered (Ok a)
instance Rewrapped (Ok a) (Ok a')
instance Wrapped (Ok a) where
type Unwrapped (Ok a) = a
_Wrapped' = iso (\(Ok a) -> a) Ok
type instance PolyBind Ok Ok = Ok
type instance PolyBind (Error e) a = Error e
type instance PolyBind Ok (Error e) = Error e
instance PolyApplicative (Error e) a where _ <<*>> _ = Error
instance PolyApplicative (Error e)(Error e) where _ <<*>> _ = Error
instance PolyApplicative Ok (Error e) where _ <<*>> _ = Error
instance PolyMonad (Error e) a where _ >>>= _ = Error
instance PolyMonad Ok (Error e) where Ok a >>>= f = f a
class CompilationError a
class Check a (ok :: Bool)
instance Check a 'True
instance CompilationError a => Check a 'False
type family Asserted e check where Asserted e 'True = Ok
Asserted e 'False = Error e
class Assert e (ok :: Bool) where assert :: Proxy e -> Proxy ok -> a -> Asserted e ok a
instance Assert e 'True where assert _ _ = Ok
instance Assert e 'False where assert _ _ _ = Error