hint-0.9.0.8: A Haskell interpreter built on top of the GHC API

Safe Haskell | None
Language | Haskell2010

Language.Haskell.Interpreter

Contents

- The interpreter monad transformer
  - Running the interpreter
  - Interpreter options
  - Context handling
  - Module querying
  - Annotations
  - Type inference
  - Evaluation
- Error handling
- Miscellaneous

Synopsis

- class (MonadIO m, MonadMask m) => MonadInterpreter (m :: Type -> Type) where
  - fromSession :: FromSession m a
  - modifySessionRef :: ModifySessionRef m a
  - runGhc :: RunGhc m a
- data InterpreterT (m :: Type -> Type) a
- type Interpreter = InterpreterT IO
- runInterpreter :: (MonadIO m, MonadMask m) => InterpreterT m a -> m (Either InterpreterError a)
- data Option (m :: Type -> Type) a
- data OptionVal (m :: Type -> Type) = (Option m a) := a
- get :: MonadInterpreter m => Option m a -> m a
- set :: MonadInterpreter m => [OptionVal m] -> m ()
- languageExtensions :: forall (m :: Type -> Type). MonadInterpreter m => Option m [Extension]
- availableExtensions :: [Extension]
- data Extension
  - = OverlappingInstances
  - | UndecidableInstances
  - | IncoherentInstances
  - | DoRec
  - | RecursiveDo
  - | ParallelListComp
  - | MultiParamTypeClasses
  - | MonomorphismRestriction
  - | FunctionalDependencies
  - | Rank2Types
  - | RankNTypes
  - | PolymorphicComponents
  - | ExistentialQuantification
  - | ScopedTypeVariables
  - | PatternSignatures
  - | ImplicitParams
  - | FlexibleContexts
  - | FlexibleInstances
  - | EmptyDataDecls
  - | CPP
  - | KindSignatures
  - | BangPatterns
  - | TypeSynonymInstances
  - | TemplateHaskell
  - | ForeignFunctionInterface
  - | Arrows
  - | Generics
  - | ImplicitPrelude
  - | NamedFieldPuns
  - | PatternGuards
  - | GeneralizedNewtypeDeriving
  - | ExtensibleRecords
  - | RestrictedTypeSynonyms
  - | HereDocuments
  - | MagicHash
  - | TypeFamilies
  - | StandaloneDeriving
  - | UnicodeSyntax
  - | UnliftedFFITypes
  - | InterruptibleFFI
  - | CApiFFI
  - | LiberalTypeSynonyms
  - | TypeOperators
  - | RecordWildCards
  - | RecordPuns
  - | DisambiguateRecordFields
  - | TraditionalRecordSyntax
  - | OverloadedStrings
  - | GADTs
  - | GADTSyntax
  - | MonoPatBinds
  - | RelaxedPolyRec
  - | ExtendedDefaultRules
  - | UnboxedTuples
  - | DeriveDataTypeable
  - | DeriveGeneric
  - | DefaultSignatures
  - | InstanceSigs
  - | ConstrainedClassMethods
  - | PackageImports
  - | ImpredicativeTypes
  - | NewQualifiedOperators
  - | PostfixOperators
  - | QuasiQuotes
  - | TransformListComp
  - | MonadComprehensions
  - | ViewPatterns
  - | XmlSyntax
  - | RegularPatterns
  - | TupleSections
  - | GHCForeignImportPrim
  - | NPlusKPatterns
  - | DoAndIfThenElse
  - | MultiWayIf
  - | LambdaCase
  - | RebindableSyntax
  - | ExplicitForAll
  - | DatatypeContexts
  - | MonoLocalBinds
  - | DeriveFunctor
  - | DeriveTraversable
  - | DeriveFoldable
  - | NondecreasingIndentation
  - | SafeImports
  - | Safe
  - | Trustworthy
  - | Unsafe
  - | ConstraintKinds
  - | PolyKinds
  - | DataKinds
  - | ParallelArrays
  - | RoleAnnotations
  - | OverloadedLists
  - | EmptyCase
  - | AutoDeriveTypeable
  - | NegativeLiterals
  - | BinaryLiterals
  - | NumDecimals
  - | NullaryTypeClasses
  - | ExplicitNamespaces
  - | AllowAmbiguousTypes
  - | JavaScriptFFI
  - | PatternSynonyms
  - | PartialTypeSignatures
  - | NamedWildCards
  - | DeriveAnyClass
  - | DeriveLift
  - | StaticPointers
  - | StrictData
  - | Strict
  - | ApplicativeDo
  - | DuplicateRecordFields
  - | TypeApplications
  - | TypeInType
  - | UndecidableSuperClasses
  - | MonadFailDesugaring
  - | TemplateHaskellQuotes
  - | OverloadedLabels
  - | TypeFamilyDependencies
  - | NoOverlappingInstances
  - | NoUndecidableInstances
  - | NoIncoherentInstances
  - | NoDoRec
  - | NoRecursiveDo
  - | NoParallelListComp
  - | NoMultiParamTypeClasses
  - | NoMonomorphismRestriction
  - | NoFunctionalDependencies
  - | NoRank2Types
  - | NoRankNTypes
  - | NoPolymorphicComponents
  - | NoExistentialQuantification
  - | NoScopedTypeVariables
  - | NoPatternSignatures
  - | NoImplicitParams
  - | NoFlexibleContexts
  - | NoFlexibleInstances
  - | NoEmptyDataDecls
  - | NoCPP
  - | NoKindSignatures
  - | NoBangPatterns
  - | NoTypeSynonymInstances
  - | NoTemplateHaskell
  - | NoForeignFunctionInterface
  - | NoArrows
  - | NoGenerics
  - | NoImplicitPrelude
  - | NoNamedFieldPuns
  - | NoPatternGuards
  - | NoGeneralizedNewtypeDeriving
  - | NoExtensibleRecords
  - | NoRestrictedTypeSynonyms
  - | NoHereDocuments
  - | NoMagicHash
  - | NoTypeFamilies
  - | NoStandaloneDeriving
  - | NoUnicodeSyntax
  - | NoUnliftedFFITypes
  - | NoInterruptibleFFI
  - | NoCApiFFI
  - | NoLiberalTypeSynonyms
  - | NoTypeOperators
  - | NoRecordWildCards
  - | NoRecordPuns
  - | NoDisambiguateRecordFields
  - | NoTraditionalRecordSyntax
  - | NoOverloadedStrings
  - | NoGADTs
  - | NoGADTSyntax
  - | NoMonoPatBinds
  - | NoRelaxedPolyRec
  - | NoExtendedDefaultRules
  - | NoUnboxedTuples
  - | NoDeriveDataTypeable
  - | NoDeriveGeneric
  - | NoDefaultSignatures
  - | NoInstanceSigs
  - | NoConstrainedClassMethods
  - | NoPackageImports
  - | NoImpredicativeTypes
  - | NoNewQualifiedOperators
  - | NoPostfixOperators
  - | NoQuasiQuotes
  - | NoTransformListComp
  - | NoMonadComprehensions
  - | NoViewPatterns
  - | NoXmlSyntax
  - | NoRegularPatterns
  - | NoTupleSections
  - | NoGHCForeignImportPrim
  - | NoNPlusKPatterns
  - | NoDoAndIfThenElse
  - | NoMultiWayIf
  - | NoLambdaCase
  - | NoRebindableSyntax
  - | NoExplicitForAll
  - | NoDatatypeContexts
  - | NoMonoLocalBinds
  - | NoDeriveFunctor
  - | NoDeriveTraversable
  - | NoDeriveFoldable
  - | NoNondecreasingIndentation
  - | NoSafeImports
  - | NoSafe
  - | NoTrustworthy
  - | NoUnsafe
  - | NoConstraintKinds
  - | NoPolyKinds
  - | NoDataKinds
  - | NoParallelArrays
  - | NoRoleAnnotations
  - | NoOverloadedLists
  - | NoEmptyCase
  - | NoAutoDeriveTypeable
  - | NoNegativeLiterals
  - | NoBinaryLiterals
  - | NoNumDecimals
  - | NoNullaryTypeClasses
  - | NoExplicitNamespaces
  - | NoAllowAmbiguousTypes
  - | NoJavaScriptFFI
  - | NoPatternSynonyms
  - | NoPartialTypeSignatures
  - | NoNamedWildCards
  - | NoDeriveAnyClass
  - | NoDeriveLift
  - | NoStaticPointers
  - | NoStrictData
  - | NoStrict
  - | NoApplicativeDo
  - | NoDuplicateRecordFields
  - | NoTypeApplications
  - | NoTypeInType
  - | NoUndecidableSuperClasses
  - | NoMonadFailDesugaring
  - | NoTemplateHaskellQuotes
  - | NoOverloadedLabels
  - | NoTypeFamilyDependencies
  - | UnknownExtension String
- installedModulesInScope :: forall (m :: Type -> Type). MonadInterpreter m => Option m Bool
- searchPath :: forall (m :: Type -> Type). MonadInterpreter m => Option m [FilePath]
- type ModuleName = String
- isModuleInterpreted :: MonadInterpreter m => ModuleName -> m Bool
- data ModuleImport = ModuleImport {
  - modName :: String
  - modQual :: ModuleQualification
  - modImp :: ImportList
  }
- data ModuleQualification
  - = NotQualified
  - | ImportAs String
  - | QualifiedAs (Maybe String)
- data ImportList
  - = NoImportList
  - | ImportList [String]
  - | HidingList [String]
- loadModules :: MonadInterpreter m => [String] -> m ()
- getLoadedModules :: MonadInterpreter m => m [ModuleName]
- setTopLevelModules :: MonadInterpreter m => [ModuleName] -> m ()
- setImports :: MonadInterpreter m => [ModuleName] -> m ()
- setImportsQ :: MonadInterpreter m => [(ModuleName, Maybe String)] -> m ()
- setImportsF :: MonadInterpreter m => [ModuleImport] -> m ()
- reset :: MonadInterpreter m => m ()
- data ModuleElem
  - = Fun Id
  - | Class Id [Id]
  - | Data Id [Id]
- type Id = String
- name :: ModuleElem -> Id
- children :: ModuleElem -> [Id]
- getModuleExports :: MonadInterpreter m => ModuleName -> m [ModuleElem]
- getModuleAnnotations :: (Data a, MonadInterpreter m) => a -> String -> m [a]
- getValAnnotations :: (Data a, MonadInterpreter m) => a -> String -> m [a]
- typeChecksWithDetails :: MonadInterpreter m => String -> m (Either [GhcError] String)
- typeOf :: MonadInterpreter m => String -> m String
- typeChecks :: MonadInterpreter m => String -> m Bool
- kindOf :: MonadInterpreter m => String -> m String
- normalizeType :: MonadInterpreter m => String -> m String
- interpret :: (MonadInterpreter m, Typeable a) => String -> a -> m a
- as :: Typeable a => a
- infer :: Typeable a => a
- eval :: MonadInterpreter m => String -> m String
- runStmt :: MonadInterpreter m => String -> m ()
- data InterpreterError
  - = UnknownError String
  - | WontCompile [GhcError]
  - | NotAllowed String
  - | GhcException String
- newtype GhcError = GhcError {
  - errMsg :: String
  }
- data MultipleInstancesNotAllowed = MultipleInstancesNotAllowed
- ghcVersion :: Int
- parens :: String -> String
- module Control.Monad.Trans.Class
- module Control.Monad.IO.Class

# The interpreter monad transformer

class (MonadIO m, MonadMask m) => MonadInterpreter (m :: Type -> Type) where Source #

Methods

fromSession :: FromSession m a Source #

modifySessionRef :: ModifySessionRef m a Source #

runGhc :: RunGhc m a Source #

#### Instances

Instances details

(MonadIO m, MonadMask m, Functor m) => MonadInterpreter (InterpreterT m) Source # |
Instance details Defined in Hint.InterpreterT Methods fromSession :: FromSession (InterpreterT m) a Source # modifySessionRef :: ModifySessionRef (InterpreterT m) a Source # runGhc :: RunGhc (InterpreterT m) a Source #

data InterpreterT (m :: Type -> Type) a Source #

#### Instances

Instances details

MonadTrans InterpreterT Source # |
Instance details Defined in Hint.InterpreterT Methods lift :: Monad m => m a -> InterpreterT m a Source #
MonadIO m => MonadIO (InterpreterT m) Source # |
Instance details Defined in Hint.InterpreterT Methods liftIO :: IO a -> InterpreterT m a Source #
(MonadIO m, MonadMask m) => MonadCatch (InterpreterT m) Source # |
Instance details Defined in Hint.InterpreterT Methods catch :: (HasCallStack, Exception e) => InterpreterT m a -> (e -> InterpreterT m a) -> InterpreterT m a Source #
(MonadIO m, MonadMask m) => MonadMask (InterpreterT m) Source # |

Instance details

Defined in Hint.InterpreterT

Methods

mask :: HasCallStack => ((forall a. InterpreterT m a -> InterpreterT m a) -> InterpreterT m b) -> InterpreterT m b Source #

uninterruptibleMask :: HasCallStack => ((forall a. InterpreterT m a -> InterpreterT m a) -> InterpreterT m b) -> InterpreterT m b Source #

generalBracket :: HasCallStack => InterpreterT m a -> (a -> ExitCase b -> InterpreterT m c) -> (a -> InterpreterT m b) -> InterpreterT m (b, c) Source #

MonadCatch m => MonadThrow (InterpreterT m) Source # |
Instance details Defined in Hint.InterpreterT Methods throwM :: (HasCallStack, Exception e) => e -> InterpreterT m a Source #
Monad m => Applicative (InterpreterT m) Source # |

Instance details

Defined in Hint.InterpreterT

Methods

pure :: a -> InterpreterT m a Source #

(<*>) :: InterpreterT m (a -> b) -> InterpreterT m a -> InterpreterT m b Source #

liftA2 :: (a -> b -> c) -> InterpreterT m a -> InterpreterT m b -> InterpreterT m c Source #

(*>) :: InterpreterT m a -> InterpreterT m b -> InterpreterT m b Source #

(<*) :: InterpreterT m a -> InterpreterT m b -> InterpreterT m a Source #

Functor m => Functor (InterpreterT m) Source # |
Instance details Defined in Hint.InterpreterT Methods fmap :: (a -> b) -> InterpreterT m a -> InterpreterT m b Source # (<$) :: a -> InterpreterT m b -> InterpreterT m a Source #
Monad m => Monad (InterpreterT m) Source # |
Instance details Defined in Hint.InterpreterT Methods (>>=) :: InterpreterT m a -> (a -> InterpreterT m b) -> InterpreterT m b Source # (>>) :: InterpreterT m a -> InterpreterT m b -> InterpreterT m b Source # return :: a -> InterpreterT m a Source #
(MonadIO m, MonadMask m, Functor m) => MonadInterpreter (InterpreterT m) Source # |
Instance details Defined in Hint.InterpreterT Methods fromSession :: FromSession (InterpreterT m) a Source # modifySessionRef :: ModifySessionRef (InterpreterT m) a Source # runGhc :: RunGhc (InterpreterT m) a Source #

type Interpreter = InterpreterT IO Source #

## Running the interpreter

runInterpreter :: (MonadIO m, MonadMask m) => InterpreterT m a -> m (Either InterpreterError a) Source #

Executes the interpreter. Returns `Left InterpreterError` in case of error.

NB. In hint-0.7.0 and earlier, the underlying ghc was accidentally overwriting certain signal handlers (SIGINT, SIGHUP, SIGTERM, SIGQUIT on Posix systems, Ctrl-C handler on Windows).

## Interpreter options

data Option (m :: Type -> Type) a Source #

Available options are:

- `languageExtensions`
- `installedModulesInScope`
- `searchPath`

data OptionVal (m :: Type -> Type) Source #

Constructors

(Option m a) := a |

get :: MonadInterpreter m => Option m a -> m a Source #

Retrieves the value of an option.

set :: MonadInterpreter m => [OptionVal m] -> m () Source #

Use this function to set or modify the value of any option. It is invoked like this:

    set [opt1 := val1, opt2 := val2,... optk := valk]

languageExtensions :: forall (m :: Type -> Type). MonadInterpreter m => Option m [Extension] Source #

Language extensions in use by the interpreter.

Default is: `[]` (i.e. none, pure Haskell 98)

availableExtensions :: [Extension] Source #

List of the extensions known by the interpreter.

data Extension Source #

This represents language extensions beyond Haskell 98 that are supported by GHC (it was taken from Cabal's `Language.Haskell.Extension`)

Constructors

OverlappingInstances |
UndecidableInstances |
IncoherentInstances |
DoRec |
RecursiveDo |
ParallelListComp |
MultiParamTypeClasses |
MonomorphismRestriction |
FunctionalDependencies |
Rank2Types |
RankNTypes |
PolymorphicComponents |
ExistentialQuantification |
ScopedTypeVariables |
PatternSignatures |
ImplicitParams |
FlexibleContexts |
FlexibleInstances |
EmptyDataDecls |
CPP |
KindSignatures |
BangPatterns |
TypeSynonymInstances |
TemplateHaskell |
ForeignFunctionInterface |
Arrows |
Generics |
ImplicitPrelude |
NamedFieldPuns |
PatternGuards |
GeneralizedNewtypeDeriving |
ExtensibleRecords |
RestrictedTypeSynonyms |
HereDocuments |
MagicHash |
TypeFamilies |
StandaloneDeriving |
UnicodeSyntax |
UnliftedFFITypes |
InterruptibleFFI |
CApiFFI |
LiberalTypeSynonyms |
TypeOperators |
RecordWildCards |
RecordPuns |
DisambiguateRecordFields |
TraditionalRecordSyntax |
OverloadedStrings |
GADTs |
GADTSyntax |
MonoPatBinds |
RelaxedPolyRec |
ExtendedDefaultRules |
UnboxedTuples |
DeriveDataTypeable |
DeriveGeneric |
DefaultSignatures |
InstanceSigs |
ConstrainedClassMethods |
PackageImports |
ImpredicativeTypes |
NewQualifiedOperators |
PostfixOperators |
QuasiQuotes |
TransformListComp |
MonadComprehensions |
ViewPatterns |
XmlSyntax |
RegularPatterns |
TupleSections |
GHCForeignImportPrim |
NPlusKPatterns |
DoAndIfThenElse |
MultiWayIf |
LambdaCase |
RebindableSyntax |
ExplicitForAll |
DatatypeContexts |
MonoLocalBinds |
DeriveFunctor |
DeriveTraversable |
DeriveFoldable |
NondecreasingIndentation |
SafeImports |
Safe |
Trustworthy |
Unsafe |
ConstraintKinds |
PolyKinds |
DataKinds |
ParallelArrays |
RoleAnnotations |
OverloadedLists |
EmptyCase |
AutoDeriveTypeable |
NegativeLiterals |
BinaryLiterals |
NumDecimals |
NullaryTypeClasses |
ExplicitNamespaces |
AllowAmbiguousTypes |
JavaScriptFFI |
PatternSynonyms |
PartialTypeSignatures |
NamedWildCards |
DeriveAnyClass |
DeriveLift |
StaticPointers |
StrictData |
Strict |
ApplicativeDo |
DuplicateRecordFields |
TypeApplications |
TypeInType |
UndecidableSuperClasses |
MonadFailDesugaring |
TemplateHaskellQuotes |
OverloadedLabels |
TypeFamilyDependencies |
NoOverlappingInstances |
NoUndecidableInstances |
NoIncoherentInstances |
NoDoRec |
NoRecursiveDo |
NoParallelListComp |
NoMultiParamTypeClasses |
NoMonomorphismRestriction |
NoFunctionalDependencies |
NoRank2Types |
NoRankNTypes |
NoPolymorphicComponents |
NoExistentialQuantification |
NoScopedTypeVariables |
NoPatternSignatures |
NoImplicitParams |
NoFlexibleContexts |
NoFlexibleInstances |
NoEmptyDataDecls |
NoCPP |
NoKindSignatures |
NoBangPatterns |
NoTypeSynonymInstances |
NoTemplateHaskell |
NoForeignFunctionInterface |
NoArrows |
NoGenerics |
NoImplicitPrelude |
NoNamedFieldPuns |
NoPatternGuards |
NoGeneralizedNewtypeDeriving |
NoExtensibleRecords |
NoRestrictedTypeSynonyms |
NoHereDocuments |
NoMagicHash |
NoTypeFamilies |
NoStandaloneDeriving |
NoUnicodeSyntax |
NoUnliftedFFITypes |
NoInterruptibleFFI |
NoCApiFFI |
NoLiberalTypeSynonyms |
NoTypeOperators |
NoRecordWildCards |
NoRecordPuns |
NoDisambiguateRecordFields |
NoTraditionalRecordSyntax |
NoOverloadedStrings |
NoGADTs |
NoGADTSyntax |
NoMonoPatBinds |
NoRelaxedPolyRec |
NoExtendedDefaultRules |
NoUnboxedTuples |
NoDeriveDataTypeable |
NoDeriveGeneric |
NoDefaultSignatures |
NoInstanceSigs |
NoConstrainedClassMethods |
NoPackageImports |
NoImpredicativeTypes |
NoNewQualifiedOperators |
NoPostfixOperators |
NoQuasiQuotes |
NoTransformListComp |
NoMonadComprehensions |
NoViewPatterns |
NoXmlSyntax |
NoRegularPatterns |
NoTupleSections |
NoGHCForeignImportPrim |
NoNPlusKPatterns |
NoDoAndIfThenElse |
NoMultiWayIf |
NoLambdaCase |
NoRebindableSyntax |
NoExplicitForAll |
NoDatatypeContexts |
NoMonoLocalBinds |
NoDeriveFunctor |
NoDeriveTraversable |
NoDeriveFoldable |
NoNondecreasingIndentation |
NoSafeImports |
NoSafe |
NoTrustworthy |
NoUnsafe |
NoConstraintKinds |
NoPolyKinds |
NoDataKinds |
NoParallelArrays |
NoRoleAnnotations |
NoOverloadedLists |
NoEmptyCase |
NoAutoDeriveTypeable |
NoNegativeLiterals |
NoBinaryLiterals |
NoNumDecimals |
NoNullaryTypeClasses |
NoExplicitNamespaces |
NoAllowAmbiguousTypes |
NoJavaScriptFFI |
NoPatternSynonyms |
NoPartialTypeSignatures |
NoNamedWildCards |
NoDeriveAnyClass |
NoDeriveLift |
NoStaticPointers |
NoStrictData |
NoStrict |
NoApplicativeDo |
NoDuplicateRecordFields |
NoTypeApplications |
NoTypeInType |
NoUndecidableSuperClasses |
NoMonadFailDesugaring |
NoTemplateHaskellQuotes |
NoOverloadedLabels |
NoTypeFamilyDependencies |
UnknownExtension String |

#### Instances

Instances details

Read Extension Source # |
Instance details Defined in Hint.Extension Methods readsPrec :: Int -> ReadS Extension Source # readList :: ReadS [Extension] Source # readPrec :: ReadPrec Extension Source # readListPrec :: ReadPrec [Extension] Source #
Show Extension Source # |
Instance details Defined in Hint.Extension Methods showsPrec :: Int -> Extension -> ShowS Source # show :: Extension -> String Source # showList :: [Extension] -> ShowS Source #
Eq Extension Source # |
Instance details Defined in Hint.Extension Methods (==) :: Extension -> Extension -> Bool Source # (/=) :: Extension -> Extension -> Bool Source #

installedModulesInScope :: forall (m :: Type -> Type). MonadInterpreter m => Option m Bool Source #

When set to `True`, every module in every available package is implicitly imported qualified. This is very convenient for interactive evaluation, but can be a problem in sandboxed environments (e.g. `unsafePerformIO` is in scope).

Default value is `True`.

Observe that due to limitations in the GHC-API, when set to `False`, the private symbols in interpreted modules will not be in scope.

searchPath :: forall (m :: Type -> Type). MonadInterpreter m => Option m [FilePath] Source #

The search path for source files. Observe that every time it is set, it overrides the previous search path. The default is `["."]`.

Keep in mind that by a limitation in ghc, `"."` is always in scope.

## Context handling

type ModuleName = String Source #

Module names are _not_ filepaths.

isModuleInterpreted :: MonadInterpreter m => ModuleName -> m Bool Source #

Returns True if the module was interpreted.

data ModuleImport Source #

Represent module import statement. See `setImportsF`

Constructors

ModuleImport |

Fields

- modName :: String
- modQual :: ModuleQualification
- modImp :: ImportList

#### Instances

Instances details

Show ModuleImport Source # |
Instance details Defined in Hint.Base Methods showsPrec :: Int -> ModuleImport -> ShowS Source # show :: ModuleImport -> String Source # showList :: [ModuleImport] -> ShowS Source #

data ModuleQualification Source #

Constructors

NotQualified |
ImportAs String |
QualifiedAs (Maybe String) |

#### Instances

Instances details

Show ModuleQualification Source # |
Instance details Defined in Hint.Base Methods showsPrec :: Int -> ModuleQualification -> ShowS Source # show :: ModuleQualification -> String Source # showList :: [ModuleQualification] -> ShowS Source #
Eq ModuleQualification Source # |
Instance details Defined in Hint.Base Methods (==) :: ModuleQualification -> ModuleQualification -> Bool Source # (/=) :: ModuleQualification -> ModuleQualification -> Bool Source #

data ImportList Source #

Constructors

NoImportList |
ImportList [String] |
HidingList [String] |

#### Instances

Instances details

Show ImportList Source # |
Instance details Defined in Hint.Base Methods showsPrec :: Int -> ImportList -> ShowS Source # show :: ImportList -> String Source # showList :: [ImportList] -> ShowS Source #
Eq ImportList Source # |
Instance details Defined in Hint.Base Methods (==) :: ImportList -> ImportList -> Bool Source # (/=) :: ImportList -> ImportList -> Bool Source #

loadModules :: MonadInterpreter m => [String] -> m () Source #

Tries to load all the requested modules from their source file. Modules my be indicated by their ModuleName (e.g. "My.Module") or by the full path to its source file. Note that in order to use code from that module, you also need to call `setImports` (to use the exported types and definitions) or `setTopLevelModules` (to also use the private types and definitions).

The interpreter is `reset` both before loading the modules and in the event of an error.

IMPORTANT: Like in a ghci session, this will also load (and interpret) any dependency that is not available via an installed package. Make sure that you are not loading any module that is also being used to compile your application. In particular, you need to avoid modules that define types that will later occur in an expression that you will want to interpret.

The problem in doing this is that those types will have two incompatible representations at runtime: 1) the one in the compiled code and 2) the one in the interpreted code. When interpreting such an expression (bringing it to program-code) you will likely get a segmentation fault, since the latter representation will be used where the program assumes the former.

The rule of thumb is: never make the interpreter run on the directory with the source code of your program! If you want your interpreted code to use some type that is defined in your program, then put the defining module on a library and make your program depend on that package.

getLoadedModules :: MonadInterpreter m => m [ModuleName] Source #

Returns the list of modules loaded with `loadModules`.

setTopLevelModules :: MonadInterpreter m => [ModuleName] -> m () Source #

Sets the modules whose context is used during evaluation. All bindings of these modules are in scope, not only those exported.

Modules must be interpreted to use this function.

setImports :: MonadInterpreter m => [ModuleName] -> m () Source #

Sets the modules whose exports must be in context. These can be modules previously loaded with `loadModules`, or modules from packages which hint is aware of. This includes package databases specified to `unsafeRunInterpreterWithArgs` by the `-package-db=...` parameter, and packages specified by a ghc environment file created by `cabal build --write-ghc-environment-files=always`.

Warning: `setImports`, `setImportsQ`, and `setImportsF` are mutually exclusive. If you have a list of modules to be used qualified and another list unqualified, then you need to do something like

     setImportsQ ((zip unqualified $ repeat Nothing) ++ qualifieds)

setImportsQ :: MonadInterpreter m => [(ModuleName, Maybe String)] -> m () Source #

A variant of `setImports` where modules them may be qualified. e.g.:

`setImportsQ [(Prelude, Nothing), (Data.Map, Just M)]`.

Here, "map" will refer to Prelude.map and "M.map" to Data.Map.map.

setImportsF :: MonadInterpreter m => [ModuleImport] -> m () Source #

A variant of `setImportsQ` where modules may have an explicit import list. e.g.:

    setImportsF [ModuleImport Prelude NotQualified NoImportList, ModuleImport Data.Text (QualifiedAs $ Just Text) (HidingList ["pack"])]

reset :: MonadInterpreter m => m () Source #

All imported modules are cleared from the context, and loaded modules are unloaded. It is similar to a `:load` in GHCi, but observe that not even the Prelude will be in context after a reset.

## Module querying

data ModuleElem Source #

Constructors

Fun Id |
Class Id [Id] |
Data Id [Id] |

#### Instances

Instances details

Read ModuleElem Source # |
Instance details Defined in Hint.Reflection Methods readsPrec :: Int -> ReadS ModuleElem Source # readList :: ReadS [ModuleElem] Source # readPrec :: ReadPrec ModuleElem Source # readListPrec :: ReadPrec [ModuleElem] Source #
Show ModuleElem Source # |
Instance details Defined in Hint.Reflection Methods showsPrec :: Int -> ModuleElem -> ShowS Source # show :: ModuleElem -> String Source # showList :: [ModuleElem] -> ShowS Source #
Eq ModuleElem Source # |
Instance details Defined in Hint.Reflection Methods (==) :: ModuleElem -> ModuleElem -> Bool Source # (/=) :: ModuleElem -> ModuleElem -> Bool Source #

type Id = String Source #

An Id for a class, a type constructor, a data constructor, a binding, etc

name :: ModuleElem -> Id Source #

children :: ModuleElem -> [Id] Source #

getModuleExports :: MonadInterpreter m => ModuleName -> m [ModuleElem] Source #

Gets an abstract representation of all the entities exported by the module. It is similar to the `:browse` command in GHCi.

## Annotations

getModuleAnnotations :: (Data a, MonadInterpreter m) => a -> String -> m [a] Source #

getValAnnotations :: (Data a, MonadInterpreter m) => a -> String -> m [a] Source #

## Type inference

typeChecksWithDetails :: MonadInterpreter m => String -> m (Either [GhcError] String) Source #

Similar to `typeChecks`, but gives more information, e.g. the type errors.

typeOf :: MonadInterpreter m => String -> m String Source #

Returns a string representation of the type of the expression.

typeChecks :: MonadInterpreter m => String -> m Bool Source #

Tests if the expression type checks.

NB. Be careful if `unsafeSetGhcOption "-fdefer-type-errors"` is used. Perhaps unsurprisingly, that can falsely make `typeChecks` and `typeChecksWithDetails` return `True` and `Right _` respectively.

kindOf :: MonadInterpreter m => String -> m String Source #

Returns a string representation of the kind of the type expression.

normalizeType :: MonadInterpreter m => String -> m String Source #

Returns a string representation of the normalized type expression. This is what the `:kind!` GHCi command prints after `=`.

## Evaluation

interpret :: (MonadInterpreter m, Typeable a) => String -> a -> m a Source #

Evaluates an expression, given a witness for its monomorphic type.

as :: Typeable a => a Source #

Convenience functions to be used with `interpret` to provide witnesses. Example:

-     interpret "head [True,False]" (as :: Bool)

-     interpret "head $ map show [True,False]" infer >>= flip interpret (as :: Bool)

infer :: Typeable a => a Source #

Convenience functions to be used with `interpret` to provide witnesses. Example:

-     interpret "head [True,False]" (as :: Bool)

-     interpret "head $ map show [True,False]" infer >>= flip interpret (as :: Bool)

eval :: MonadInterpreter m => String -> m String Source #

`eval expr` will evaluate `show expr`. It will succeed only if `expr` has type t and there is a `Show` instance for t.

runStmt :: MonadInterpreter m => String -> m () Source #

Evaluate a statement in the `IO` monad, possibly binding new names.

Example:

    runStmt "x <- return 42"
    runStmt "print x"

# Error handling

data InterpreterError Source #

Constructors

UnknownError String |
WontCompile [GhcError] |
NotAllowed String |
GhcException String | GhcExceptions from the underlying GHC API are caught and rethrown as this.

#### Instances

Instances details

Exception InterpreterError Source # |
Instance details Defined in Hint.Base Methods toException :: InterpreterError -> SomeException Source # fromException :: SomeException -> Maybe InterpreterError Source # displayException :: InterpreterError -> String Source # backtraceDesired :: InterpreterError -> Bool Source #
Show InterpreterError Source # |
Instance details Defined in Hint.Base Methods showsPrec :: Int -> InterpreterError -> ShowS Source # show :: InterpreterError -> String Source # showList :: [InterpreterError] -> ShowS Source #

newtype GhcError Source #

Constructors

GhcError |

Fields

- errMsg :: String

#### Instances

Instances details

Show GhcError Source # |
Instance details Defined in Hint.Base Methods showsPrec :: Int -> GhcError -> ShowS Source # show :: GhcError -> String Source # showList :: [GhcError] -> ShowS Source #

data MultipleInstancesNotAllowed Source #

The installed version of ghc is not thread-safe. This exception is thrown whenever you try to execute `runInterpreter` while another instance is already running.

Constructors

MultipleInstancesNotAllowed |

#### Instances

Instances details

Exception MultipleInstancesNotAllowed Source # |
Instance details Defined in Hint.InterpreterT Methods toException :: MultipleInstancesNotAllowed -> SomeException Source # fromException :: SomeException -> Maybe MultipleInstancesNotAllowed Source # displayException :: MultipleInstancesNotAllowed -> String Source # backtraceDesired :: MultipleInstancesNotAllowed -> Bool Source #
Show MultipleInstancesNotAllowed Source # |
Instance details Defined in Hint.InterpreterT Methods showsPrec :: Int -> MultipleInstancesNotAllowed -> ShowS Source # show :: MultipleInstancesNotAllowed -> String Source # showList :: [MultipleInstancesNotAllowed] -> ShowS Source #

# Miscellaneous

ghcVersion :: Int Source #

Version of the underlying ghc api. Values are:

- `804` for GHC 8.4.x
- `806` for GHC 8.6.x
- etc...

parens :: String -> String Source #

Conceptually, `parens s = "(" ++ s ++ ")"`, where s is any valid haskell expression. In practice, it is harder than this. Observe that if `s` ends with a trailing comment, then `parens s` would be a malformed expression. The straightforward solution for this is to put the closing parenthesis in a different line. However, now we are messing with the layout rules and we don't know where `s` is going to be used! Solution: `parens s = "(let {foo =\n" ++ s ++ "\n ;} in foo)"` where `foo` does not occur in `s`

module Control.Monad.Trans.Class

module Control.Monad.IO.Class