{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
module Language.PTS.Error (
MonadErr (..),
Err (..),
AsErr (..),
) where
import Prelude ()
import Prelude.Compat
import Control.Exception
import Control.Lens (Prism', review)
import Control.Monad.Error.Class (MonadError (..))
import Data.String (IsString (..))
import qualified Control.Monad.EitherK as U
import qualified Control.Unification as U
import qualified Data.Set as Set
import qualified Text.PrettyPrint.Compact as PP
import Language.PTS.Pretty
import Language.PTS.Sym
class Monad m => MonadErr m where
throwErr :: Err -> m a
instance AsErr err => MonadErr (Either err) where
throwErr = Left . review _Err
instance (AsErr err, Monad m) => MonadErr (U.EitherKT err m) where
throwErr = throwError . review _Err
instance MonadErr IO where
throwErr = throwIO
instance MonadErr Maybe where
throwErr _ = Nothing
instance (PrettyPrec1 t, PrettyPrec v) => U.Fallible t v Err where
occursFailure v t = OccursFailure (ppp PrecDef v) (ppp1 PrecDef t)
mismatchFailure a b = MismatchFailure (ppp1 PrecDef a) (ppp1 PrecDef b)
class AsErr e where
_Err :: Prism' e Err
instance AsErr Err where
_Err = id
data Err
= SomeErr String
| VariableNotInScope (PrettyM Doc) [PrettyM Doc]
| TypeMismatch (PrettyM Doc) (PrettyM Doc) (PrettyM Doc) [PrettyM Doc]
| NonEqual (PrettyM Doc) (PrettyM Doc) (PrettyM Doc) [PrettyM Doc]
| SortMismatch (PrettyM Doc) (PrettyM Doc) (PrettyM Doc) [PrettyM Doc]
| LambdaNotPi (PrettyM Doc) (PrettyM Doc) [PrettyM Doc]
| PairNotSigma (PrettyM Doc) (PrettyM Doc) [PrettyM Doc]
| ReflNotEquality (PrettyM Doc) [PrettyM Doc]
| NotAPair (PrettyM Doc) (PrettyM Doc) [PrettyM Doc]
| NoRule (PrettyM Doc) (PrettyM Doc) [PrettyM Doc]
| NotAFunction (PrettyM Doc) (PrettyM Doc) (PrettyM Doc) [PrettyM Doc]
| SortWithoutAxiom (PrettyM Doc) [PrettyM Doc]
| QuarkNotInHadron Sym (Set.Set Sym) [PrettyM Doc]
| QuarkNotHadron Sym (PrettyM Doc) [PrettyM Doc]
| ApplyPanic String (PrettyM Doc)
| OccursFailure (PrettyM Doc) (PrettyM Doc)
| MismatchFailure (PrettyM Doc) (PrettyM Doc)
instance Show Err where
showsPrec _ = showString . prettyShow
instance Exception Err
instance IsString Err where
fromString = SomeErr
instance PrettyPrec Err where
ppp _ (SomeErr err) = pppError [] [pppText err]
ppp _ (VariableNotInScope x ctx) = pppError ctx
[ "Variable not in scope" <+> x
]
ppp _ (TypeMismatch expt act term ctx) = pppError ctx
[ "Couldn't match expected type" <+> expt <+> "with actual type" <+> act
, "In the expression:" <+> term
]
ppp _ (SortMismatch expt act term ctx) = pppError ctx
[ "Couldn't match expected sort" <+> expt <+> "with actual type" <+> act
, "In the expression:" <+> term
]
ppp _ (LambdaNotPi t term ctx) = pppError ctx
[ "The lambda expression" <+> term <+> "doesn't have a Pi-type"
, "Annotated with" <+> t
]
ppp _ (PairNotSigma t term ctx) = pppError ctx
[ "The pair expression" <+> term <+> "doesn't have a Sigma-type"
, "Annotated with" <+> t
]
ppp _ (ReflNotEquality t ctx) = pppError ctx
[ "The refl doesn't have a Equality-type"
, "Annotated with" <+> t
]
ppp _ (NonEqual x y a ctx) = pppError ctx
[ "Couldn't match expected value" <+> x <+> "with value" <+> y
, "Equality of the type:" <+> a
]
ppp _ (NoRule s1 s2 ctx) = pppError ctx
[ "No PTS Rule (" <> s1 <> "," <> s2 <> ",-)"
]
ppp _ (NotAFunction t f x ctx) = pppError ctx
[ "Couldn't match actual type" <+> t <+> "with a function type"
, "In the application of" <+> f
, "to the value" <+> x
]
ppp _ (NotAPair t p ctx) = pppError ctx
[ "Couldn't match actual type" <+> t <+> "with a pair type"
, "In the match on" <+> p
]
ppp _ (QuarkNotInHadron q qs ctx) = pppError ctx
[ "The quark" <+> pppQuark q <+> "is not in hadron" <+> pppHadron qs
]
ppp _ (QuarkNotHadron q t ctx) = pppError ctx
[ "The quark" <+> pppQuark q <+> "doesn't have a Hadron type"
, "Annotated with" <+> t
]
ppp _ (SortWithoutAxiom s ctx) = pppError ctx
[ "Type-less sort" <+> s <+> "(no axiom exist)"
]
ppp _ (ApplyPanic tag f) =
"panic '" <> pppText tag <> "':" </> err
where
err = "Trying to apply not-a-lambda" <+> f
ppp _ (OccursFailure v t) = pppError []
[ "Occurs check, cannot construct infinite type" <+> v <+> " ~ " <+> t
]
ppp _ (MismatchFailure a b) = pppError []
[ "Couldn't match expected type" <+> b <+> "with actual type" <+> a
]
pppError :: [PrettyM Doc] -> [PrettyM Doc] -> PrettyM Doc
pppError [] bs = "error:" $$$ pppBullets bs
pppError ts bs = "error:" $$$ pppBullets (bs ++ [err]) where
err = "when checking expression" $$$ fmap PP.vcat (sequence ts)
pppBullets :: [PrettyM Doc] -> PrettyM Doc
pppBullets bs = PP.vcat <$> traverse (pppChar '•' <+>) bs