module Data.Res where import Control.Applicative import Data.String (IsString (fromString)) data Res e r = Ok r | Err e instance Functor (Res e) where fmap f (Ok v) = Ok (f v) fmap _ (Err e) = Err e instance Applicative (Res e) where pure = Ok (Ok f) <*> (Ok v) = Ok (f v) (Err e) <*> _ = Err e _ <*> (Err e) = Err e instance Monad (Res e) where (Ok v) >>= f = f v (Err e) >>= _ = Err e instance IsString e => MonadFail (Res e) where fail = Err . fromString instance IsString e => Alternative (Res e) where empty = fail "mzero" m1@(Ok _) <|> _ = m1 (Err _) <|> m2 = m2 liftEither :: Either e r -> Res e r liftEither = either Err Ok