module Erebos.Error ( ErebosError(..), showErebosError, FromErebosError(..), throwOtherError, ) where import Control.Monad.Except data ErebosError = ManyErrors [ ErebosError ] | OtherError String showErebosError :: ErebosError -> String showErebosError (ManyErrors errs) = unlines $ map showErebosError errs showErebosError (OtherError str) = str instance Semigroup ErebosError where ManyErrors [] <> b = b a <> ManyErrors [] = a ManyErrors a <> ManyErrors b = ManyErrors (a ++ b) ManyErrors a <> b = ManyErrors (a ++ [ b ]) a <> ManyErrors b = ManyErrors (a : b) a@OtherError {} <> b@OtherError {} = ManyErrors [ a, b ] instance Monoid ErebosError where mempty = ManyErrors [] class FromErebosError e where fromErebosError :: ErebosError -> e instance FromErebosError ErebosError where fromErebosError = id throwOtherError :: (MonadError e m, FromErebosError e) => String -> m a throwOtherError = throwError . fromErebosError . OtherError