module Hint.Typecheck (
typeOf, typeChecks, kindOf, normalizeType, onCompilationError, typeChecksWithDetails
) where
import Control.Monad.Catch
import Hint.Base
import Hint.Parsers
import Hint.Conversions
import qualified Hint.GHC as GHC
typeOf :: MonadInterpreter m => String -> m String
typeOf expr =
do
failOnParseError parseExpr expr
ty <- mayFail $ runGhc1 exprType expr
typeToString ty
typeChecks :: MonadInterpreter m => String -> m Bool
typeChecks expr = (typeOf expr >> return True)
`catchIE`
onCompilationError (\_ -> return False)
typeChecksWithDetails :: MonadInterpreter m => String -> m (Either [GhcError] String)
typeChecksWithDetails expr = (Right <$> typeOf expr)
`catchIE`
onCompilationError (return . Left)
kindOf :: MonadInterpreter m => String -> m String
kindOf type_expr =
do
failOnParseError parseType type_expr
(_, kind) <- mayFail $ runGhc1 typeKind type_expr
kindToString kind
normalizeType :: MonadInterpreter m => String -> m String
normalizeType type_expr =
do
failOnParseError parseType type_expr
(ty, _) <- mayFail $ runGhc1 typeKind type_expr
typeToString ty
exprType :: GHC.GhcMonad m => String -> m (Maybe GHC.Type)
exprType = fmap Just . GHC.exprType GHC.TM_Inst
typeKind :: GHC.GhcMonad m => String -> m (Maybe (GHC.Type, GHC.Kind))
typeKind = fmap Just . GHC.typeKind True
onCompilationError :: MonadInterpreter m
=> ([GhcError] -> m a)
-> (InterpreterError -> m a)
onCompilationError recover interp_error
= case interp_error of
WontCompile errs -> recover errs
otherErr -> throwM otherErr