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 :: String -> m String
typeOf expr :: String
expr =
do
(String -> m ParseResult) -> String -> m ()
forall (m :: * -> *).
MonadInterpreter m =>
(String -> m ParseResult) -> String -> m ()
failOnParseError String -> m ParseResult
forall (m :: * -> *). MonadInterpreter m => String -> m ParseResult
parseExpr String
expr
Type
ty <- m (Maybe Type) -> m Type
forall (m :: * -> *) a. MonadInterpreter m => m (Maybe a) -> m a
mayFail (m (Maybe Type) -> m Type) -> m (Maybe Type) -> m Type
forall a b. (a -> b) -> a -> b
$ RunGhc1 m String (Maybe Type)
forall (m :: * -> *) a b. MonadInterpreter m => RunGhc1 m a b
runGhc1 forall (n :: * -> *).
(MonadIO n, MonadMask n) =>
String -> GhcT n (Maybe Type)
forall (m :: * -> *). GhcMonad m => String -> m (Maybe Type)
exprType String
expr
Type -> m String
forall (m :: * -> *). MonadInterpreter m => Type -> m String
typeToString Type
ty
typeChecks :: MonadInterpreter m => String -> m Bool
typeChecks :: String -> m Bool
typeChecks expr :: String
expr = (String -> m String
forall (m :: * -> *). MonadInterpreter m => String -> m String
typeOf String
expr m String -> m Bool -> m Bool
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Bool -> m Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True)
m Bool -> (InterpreterError -> m Bool) -> m Bool
forall (m :: * -> *) a.
MonadInterpreter m =>
m a -> (InterpreterError -> m a) -> m a
`catchIE`
([GhcError] -> m Bool) -> InterpreterError -> m Bool
forall (m :: * -> *) a.
MonadInterpreter m =>
([GhcError] -> m a) -> InterpreterError -> m a
onCompilationError (\_ -> Bool -> m Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False)
typeChecksWithDetails :: MonadInterpreter m => String -> m (Either [GhcError] String)
typeChecksWithDetails :: String -> m (Either [GhcError] String)
typeChecksWithDetails expr :: String
expr = (String -> Either [GhcError] String
forall a b. b -> Either a b
Right (String -> Either [GhcError] String)
-> m String -> m (Either [GhcError] String)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> m String
forall (m :: * -> *). MonadInterpreter m => String -> m String
typeOf String
expr)
m (Either [GhcError] String)
-> (InterpreterError -> m (Either [GhcError] String))
-> m (Either [GhcError] String)
forall (m :: * -> *) a.
MonadInterpreter m =>
m a -> (InterpreterError -> m a) -> m a
`catchIE`
([GhcError] -> m (Either [GhcError] String))
-> InterpreterError -> m (Either [GhcError] String)
forall (m :: * -> *) a.
MonadInterpreter m =>
([GhcError] -> m a) -> InterpreterError -> m a
onCompilationError (Either [GhcError] String -> m (Either [GhcError] String)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either [GhcError] String -> m (Either [GhcError] String))
-> ([GhcError] -> Either [GhcError] String)
-> [GhcError]
-> m (Either [GhcError] String)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [GhcError] -> Either [GhcError] String
forall a b. a -> Either a b
Left)
kindOf :: MonadInterpreter m => String -> m String
kindOf :: String -> m String
kindOf type_expr :: String
type_expr =
do
(String -> m ParseResult) -> String -> m ()
forall (m :: * -> *).
MonadInterpreter m =>
(String -> m ParseResult) -> String -> m ()
failOnParseError String -> m ParseResult
forall (m :: * -> *). MonadInterpreter m => String -> m ParseResult
parseType String
type_expr
(_, kind :: Type
kind) <- m (Maybe (Type, Type)) -> m (Type, Type)
forall (m :: * -> *) a. MonadInterpreter m => m (Maybe a) -> m a
mayFail (m (Maybe (Type, Type)) -> m (Type, Type))
-> m (Maybe (Type, Type)) -> m (Type, Type)
forall a b. (a -> b) -> a -> b
$ RunGhc1 m String (Maybe (Type, Type))
forall (m :: * -> *) a b. MonadInterpreter m => RunGhc1 m a b
runGhc1 forall (n :: * -> *).
(MonadIO n, MonadMask n) =>
String -> GhcT n (Maybe (Type, Type))
forall (m :: * -> *).
GhcMonad m =>
String -> m (Maybe (Type, Type))
typeKind String
type_expr
Type -> m String
forall (m :: * -> *). MonadInterpreter m => Type -> m String
kindToString Type
kind
normalizeType :: MonadInterpreter m => String -> m String
normalizeType :: String -> m String
normalizeType type_expr :: String
type_expr =
do
(String -> m ParseResult) -> String -> m ()
forall (m :: * -> *).
MonadInterpreter m =>
(String -> m ParseResult) -> String -> m ()
failOnParseError String -> m ParseResult
forall (m :: * -> *). MonadInterpreter m => String -> m ParseResult
parseType String
type_expr
(ty :: Type
ty, _) <- m (Maybe (Type, Type)) -> m (Type, Type)
forall (m :: * -> *) a. MonadInterpreter m => m (Maybe a) -> m a
mayFail (m (Maybe (Type, Type)) -> m (Type, Type))
-> m (Maybe (Type, Type)) -> m (Type, Type)
forall a b. (a -> b) -> a -> b
$ RunGhc1 m String (Maybe (Type, Type))
forall (m :: * -> *) a b. MonadInterpreter m => RunGhc1 m a b
runGhc1 forall (n :: * -> *).
(MonadIO n, MonadMask n) =>
String -> GhcT n (Maybe (Type, Type))
forall (m :: * -> *).
GhcMonad m =>
String -> m (Maybe (Type, Type))
typeKind String
type_expr
Type -> m String
forall (m :: * -> *). MonadInterpreter m => Type -> m String
typeToString Type
ty
exprType :: GHC.GhcMonad m => String -> m (Maybe GHC.Type)
exprType :: String -> m (Maybe Type)
exprType = (Type -> Maybe Type) -> m Type -> m (Maybe Type)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Type -> Maybe Type
forall a. a -> Maybe a
Just (m Type -> m (Maybe Type))
-> (String -> m Type) -> String -> m (Maybe Type)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TcRnExprMode -> String -> m Type
forall (m :: * -> *).
GhcMonad m =>
TcRnExprMode -> String -> m Type
GHC.exprType TcRnExprMode
GHC.TM_Inst
typeKind :: GHC.GhcMonad m => String -> m (Maybe (GHC.Type, GHC.Kind))
typeKind :: String -> m (Maybe (Type, Type))
typeKind = ((Type, Type) -> Maybe (Type, Type))
-> m (Type, Type) -> m (Maybe (Type, Type))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Type, Type) -> Maybe (Type, Type)
forall a. a -> Maybe a
Just (m (Type, Type) -> m (Maybe (Type, Type)))
-> (String -> m (Type, Type)) -> String -> m (Maybe (Type, Type))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> String -> m (Type, Type)
forall (m :: * -> *).
GhcMonad m =>
Bool -> String -> m (Type, Type)
GHC.typeKind Bool
True
onCompilationError :: MonadInterpreter m
=> ([GhcError] -> m a)
-> (InterpreterError -> m a)
onCompilationError :: ([GhcError] -> m a) -> InterpreterError -> m a
onCompilationError recover :: [GhcError] -> m a
recover interp_error :: InterpreterError
interp_error
= case InterpreterError
interp_error of
WontCompile errs :: [GhcError]
errs -> [GhcError] -> m a
recover [GhcError]
errs
otherErr :: InterpreterError
otherErr -> InterpreterError -> m a
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM InterpreterError
otherErr