open import Library.Monad open import Level module Library.Error where open import Data.Sum.Base using (_⊎_; inj₁; inj₂) module ErrorMonad {e} {E : Set e} where Error : ∀{a} (A : Set a) → Set (e ⊔ a) Error A = E ⊎ A pattern fail err = inj₁ err pattern ok val = inj₂ val instance functorError : ∀ {a} → Functor (Error {a}) fmap {{functorError}} f (fail err) = fail err fmap {{functorError}} f (ok a ) = ok (f a) applicativeError : ∀ {a} → Applicative (Error {a}) pure {{applicativeError}} = ok _<*>_ {{applicativeError}} (fail err) x = fail err _<*>_ {{applicativeError}} (ok f ) x = f <$> x monadError : ∀ {a} → Monad (Error {a}) _>>=_ {{monadError}} (fail err) k = fail err _>>=_ {{monadError}} (ok a ) k = k a liftM2 : ∀ {ℓ} {A B C : Set ℓ} (f : A → B → C) → Error A → Error B → Error C liftM2 f m n = f <$> m <*> n throwError : ∀{a} {A : Set a} → E → Error A throwError = fail catchError : ∀{a} {A : Set a} → Error A → (E → Error A) → Error A catchError (fail e) h = h e catchError (ok a) h = ok a