th-tc-0.2.1.0: Typechecking in Template Haskell

Safe HaskellNone
LanguageHaskell2010

Language.Haskell.TH.Typecheck

Description

Poor man's typechecker in Template Haskell. Capable of working with type synonyms, type families, DataKinds, kind polymorphism.

Levity polymorphism is currently not supported. Return kind inference in type families is not supported.

GHC cannot reify roles correctly, so we cannot solve Coercible constraints correctly, so instance resolution was left out.

Synopsis

Documentation

type MonadTc m = (Quasi m, MonadState TcScope m) Source #

Constraints for the typechecking monad. You probably want to use m ~ StateT TcScope Q

data TcScope Source #

Scope of the typechecker. Includes information about unificational vs rigid (skolem) type variables, and a cache of type information reified from GHC.

runTc :: Monad m => StateT TcScope m a -> m a Source #

Execute a typechecker computation. Unificational variables will not persist between different runTc blocks.

type TV = Name Source #

Type variable.

freshUnifTV :: MonadTc m => m TV Source #

Make a fresh (unused) unificational type variable. Unification will be able to replace this type variable with a concrete type.

class HasTV a where Source #

A class for thigns that contain type variables.

Minimal complete definition

instantiating, occurrences

Methods

instantiate :: MonadTc m => a -> m a Source #

Replace all free variables with fresh unificational type variables.

instantiating :: MonadTc m => a -> StateT (Map TV TV) m a Source #

Replace all free variables with fresh unificational type variables, in a state transformer.

occurrences :: a -> Set TV Source #

Free variables.

Instances
HasTV Type Source # 
Instance details

Defined in Language.Haskell.TH.Typecheck

HasTV Name Source # 
Instance details

Defined in Language.Haskell.TH.Typecheck

HasTV a => HasTV [a] Source # 
Instance details

Defined in Language.Haskell.TH.Typecheck

Methods

instantiate :: MonadTc m => [a] -> m [a] Source #

instantiating :: MonadTc m => [a] -> StateT (Map TV TV) m [a] Source #

occurrences :: [a] -> Set TV Source #

(HasTV a, HasTV b) => HasTV (a, b) Source # 
Instance details

Defined in Language.Haskell.TH.Typecheck

Methods

instantiate :: MonadTc m => (a, b) -> m (a, b) Source #

instantiating :: MonadTc m => (a, b) -> StateT (Map TV TV) m (a, b) Source #

occurrences :: (a, b) -> Set TV Source #

extractKind :: MonadTc m => Type -> m Kind Source #

Attempt to compute the kind of a type. GHC doesn't give us complete kind information so this migth be more general than expected.

unifyTy :: MonadTc m => Type -> Type -> m () Source #

Assert that two types are equal, and replace unificational variables as necessary. Throws an error if the two types cannot be shown equal.

unifyTys :: MonadTc m => [Type] -> [Type] -> m () Source #

Assert that two lists of types are equal, replace unificational variables as necessary. Throws an error if two corresponding types could not be shown to be equal, or if lists have different lengths.

data UnifyResult Source #

Result of unification

Constructors

Apart String

The types are known to be different. (Includes an error message for if the types were expected to be equal).

Unknown String

The types may be different depending on substitutions of rigid type variables or not-yet-known type family instances. (Includes an error message for if the types were expected to be equal).

Equal

The types are known to be equal

unifyTyResult :: MonadTc m => Type -> Type -> m UnifyResult Source #

Attempt unification and return an indication of whether the types were equal or not.

unifyTysResult :: MonadTc m => [Type] -> [Type] -> m UnifyResult Source #

Attempt unifying two lists of types. If any two corresponding types in the lists are apart, returns Apart. If the lists are of different lengths, returns Apart.

extractSubst :: MonadTc m => Type -> m [(TV, Type)] Source #

Recursively collect all zonked (unified with a type) unificational variables in the type, into a substitution. This is a separate step because we cannot actually replace the variables as the data structure is immutable.

substZonked :: MonadTc m => Type -> m Type Source #

Recursively replace all zonked unificational variables in the type.