-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | A simply typed lambda calculus interpreter, written with GADTs -- @package glambda @version 1.0.1 -- | Utility exports (and re-exports) for glambda. This module is meant to -- be internal -- do not import it if you are not part of the glambda -- package! module Language.Glambda.Util -- | Convert a Doc to a String render :: Doc -> String -- | Convert a Doc to a SimpleDoc for further rendering toSimpleDoc :: Doc -> SimpleDoc -- | Enclose a Doc in parens if the flag is True maybeParens :: Bool -> Doc -> Doc -- | Synonym for <$> ($$) :: Doc -> Doc -> Doc -- | More perspicuous synonym for operator precedence type Prec = Rational -- | Precedence for top-level printing topPrec :: Prec -- | (Inefficiently) strips whitespace from a string stripWhitespace :: String -> String -- | Pluck out the nth item from a list, or use a default if the list is -- too short nthDefault :: a -> Int -> [a] -> a -- | Propositional equality. If a :~: b is inhabited by some -- terminating value, then the type a is the same as the type -- b. To use this equality in practice, pattern-match on the -- a :~: b to get out the Refl constructor; in the body -- of the pattern-match, the compiler knows that a ~ b. -- -- Since: 4.7.0.0 data (:~:) (a :: k) (b :: k) :: k -> k -> * Refl :: (:~:) k a1 a1 -- | Like void ignore :: Functor f => f a -> f () instance Pretty ParseError -- | Defines types module Language.Glambda.Type -- | Representation of a glambda type data Ty -- | A function type Arr :: Ty -> Ty -> Ty IntTy :: Ty BoolTy :: Ty -- | Perhaps convert a string representation of a base type into a -- Ty readTyCon :: String -> Maybe Ty -- | Singleton for a glambda type data STy :: * -> * SArr :: STy arg -> STy res -> STy (arg -> res) SIntTy :: STy Int SBoolTy :: STy Bool -- | Singleton for a typing context data SCtx :: [*] -> * SNil :: SCtx [] SCons :: STy h -> SCtx t -> SCtx (h : t) -- | An implicit STy, wrapped up in a class constraint class ITy ty sty :: ITy ty => STy ty -- | The singleton for the empty context emptyContext :: SCtx [] -- | Convert a Ty into an STy. refineTy :: Ty -> (forall ty. STy ty -> r) -> r -- | Convert an STy into a Ty unrefineTy :: STy ty -> Ty -- | Compare two STys for equality. eqSTy :: STy ty1 -> STy ty2 -> Maybe (ty1 :~: ty2) instance Eq Ty instance Pretty (STy ty) instance Show Ty instance Pretty Ty instance ITy Bool instance ITy Int instance (ITy arg, ITy res) => ITy (arg -> res) -- | Defines a lexical token module Language.Glambda.Token -- | An ArithOp ty is an operator on numbers that produces a -- result of type ty data ArithOp ty Plus :: ArithOp Int Minus :: ArithOp Int Times :: ArithOp Int Divide :: ArithOp Int Mod :: ArithOp Int Less :: ArithOp Bool LessE :: ArithOp Bool Greater :: ArithOp Bool GreaterE :: ArithOp Bool Equals :: ArithOp Bool -- | UArithOp ("unchecked ArithOp") is an existential package -- for an ArithOp data UArithOp UArithOp :: ArithOp ty -> UArithOp -- | Compare two ArithOps (potentially of different types) for -- equality eqArithOp :: ArithOp ty1 -> ArithOp ty2 -> Bool uPlus :: UArithOp uMinus :: UArithOp uTimes :: UArithOp uDivide :: UArithOp uMod :: UArithOp uLess :: UArithOp uLessE :: UArithOp uGreater :: UArithOp uGreaterE :: UArithOp uEquals :: UArithOp -- | A lexed token data Token LParen :: Token RParen :: Token Lambda :: Token Dot :: Token Arrow :: Token Colon :: Token ArithOp :: UArithOp -> Token Int :: Int -> Token Bool :: Bool -> Token If :: Token Then :: Token Else :: Token FixT :: Token Assign :: Token Semi :: Token Name :: String -> Token -- | A lexed token with location information attached data LToken L :: SourcePos -> Token -> LToken -- | Remove location information from an LToken unLoc :: LToken -> Token -- | Perhaps extract a UArithOp unArithOp :: Token -> Maybe UArithOp -- | Perhaps extract an Int unInt :: Token -> Maybe Int -- | Perhaps extract an Bool unBool :: Token -> Maybe Bool -- | Perhaps extract a String unName :: Token -> Maybe String instance Eq Token instance Show LToken instance Pretty LToken instance Show Token instance Pretty Token instance Show UArithOp instance Pretty UArithOp instance Show (ArithOp ty) instance Pretty (ArithOp ty) instance Eq UArithOp instance Eq (ArithOp ty) -- | Pretty-printing expressions. This allows reduction of code duplication -- between unchecked and checked expressions. module Language.Glambda.Pretty -- | A class for expressions that can be pretty-printed class Pretty exp => PrettyExp exp prettyExp :: PrettyExp exp => Coloring -> Prec -> exp -> Doc -- | Convenient implementation of pretty defaultPretty :: PrettyExp exp => exp -> Doc -- | Information about coloring in de Bruijn indexes and binders data Coloring -- | A Coloring for an empty context defaultColoring :: Coloring -- | Print a variable prettyVar :: Coloring -> Int -> Doc -- | Print a lambda expression prettyLam :: PrettyExp exp => Coloring -> Prec -> Maybe Ty -> exp -> Doc -- | Print an application prettyApp :: (PrettyExp exp1, PrettyExp exp2) => Coloring -> Prec -> exp1 -> exp2 -> Doc -- | Print an arithemtic expression prettyArith :: (PrettyExp exp1, PrettyExp exp2) => Coloring -> Prec -> exp1 -> ArithOp ty -> exp2 -> Doc -- | Print a conditional prettyIf :: (PrettyExp exp1, PrettyExp exp2, PrettyExp exp3) => Coloring -> Prec -> exp1 -> exp2 -> exp3 -> Doc -- | Print a fix prettyFix :: PrettyExp exp => Coloring -> Prec -> exp -> Doc -- | The Exp GADT. Glambda expressions encoded in an Exp value are -- *always* well-typed. module Language.Glambda.Exp -- | Exp ctx ty is a well-typed expression of type ty in -- context ctx. Note that a context is a list of types, where a -- type's index in the list indicates the de Bruijn index of the -- associated term-level variable. data Exp :: [*] -> * -> * Var :: Elem ctx ty -> Exp ctx ty Lam :: Exp (arg : ctx) res -> Exp ctx (arg -> res) App :: Exp ctx (arg -> res) -> Exp ctx arg -> Exp ctx res Arith :: Exp ctx Int -> ArithOp ty -> Exp ctx Int -> Exp ctx ty Cond :: Exp ctx Bool -> Exp ctx ty -> Exp ctx ty -> Exp ctx ty Fix :: Exp ctx (ty -> ty) -> Exp ctx ty IntE :: Int -> Exp ctx Int BoolE :: Bool -> Exp ctx Bool -- | Elem xs x is evidence that x is in the list -- xs. EZ :: Elem xs x is evidence that x is -- the first element of xs. ES ev :: Elem xs x is -- evidence that x is one position later in xs than is -- indicated in ev data Elem :: [a] -> a -> * EZ :: Elem (x : xs) x ES :: Elem xs x -> Elem (y : xs) x -- | Classifies types that can be values of glambda expressions class GlamVal t where data family Val t val :: GlamVal t => Val t -> Exp [] t -- | Pretty-prints a Val. This needs type information to know how to -- print. Pattern matching gives GHC enough information to be able to -- find the GlamVal instance needed to construct the -- PrettyExp instance. prettyVal :: Val t -> STy t -> Doc -- | Equality on expressions, needed for testing eqExp :: Exp ctx1 ty1 -> Exp ctx2 ty2 -> Bool instance GlamVal ty => PrettyExp (Val ty) instance GlamVal ty => Pretty (Val ty) instance PrettyExp (Exp ctx ty) instance Pretty (Exp ctx ty) instance GlamVal (a -> b) instance GlamVal Bool instance GlamVal Int -- | Manages the global variables in Glambda module Language.Glambda.Globals -- | The global variable environment maps variables to type-checked -- expressions data Globals -- | An empty global variable environment emptyGlobals :: Globals -- | Extend a Globals with a new binding extend :: String -> STy ty -> Exp [] ty -> Globals -> Globals -- | Lookup a global variable. Fails with throwError if the variable -- is not bound. lookupGlobal :: MonadError Doc m => Globals -> String -> (forall ty. STy ty -> Exp [] ty -> m r) -> m r -- | The Glam monad, allowing for pretty-printed output to the user, -- failing with an error message, and tracking global variables. module Language.Glambda.Monad -- | A monad giving Haskeline-like interaction, access to Globals, -- and the ability to abort with mzero. data Glam a -- | Run a Glam computation runGlam :: Glam () -> InputT IO () -- | Prompt the user for input, returning a string if one is entered. Like -- getInputLine. prompt :: String -> Glam (Maybe String) -- | Abort the Glam monad quit :: Glam a -- | Like the Glam monad, but also supporting error messages via -- Docs data GlamE a -- | Run a GlamE computation runGlamE :: GlamE a -> Glam (Either Doc a) -- | Abort the computation with an error issueError :: Doc -> GlamE a -- | Hoist an Either into GlamE eitherToGlamE :: Either String a -> GlamE a -- | Class for the two glamorous monads class GlamM m printDoc :: GlamM m => Doc -> m () printLine :: GlamM m => Doc -> m () instance Monad Glam instance Functor Glam instance Applicative Glam instance MonadState Globals Glam instance MonadIO Glam instance Monad GlamE instance Functor GlamE instance Applicative GlamE instance MonadError Doc GlamE instance GlamM GlamE instance GlamM Glam instance MonadReader Globals GlamE -- | de Bruijn shifting and substitution module Language.Glambda.Shift -- | Convert an expression typed in one context to one typed in a larger -- context. Operationally, this amounts to de Bruijn index shifting. As a -- proposition, this is the weakening lemma. shift :: Exp ts2 ty -> Exp (t : ts2) ty -- | Substitute the first expression into the second. As a proposition, -- this is the substitution lemma. subst :: Exp ts2 s -> Exp (s : ts2) t -> Exp ts2 t -- | Defines the AST for un-type-checked expressions module Language.Glambda.Unchecked -- | Unchecked expression data UExp -- | de Bruijn index for a variable UVar :: Int -> UExp UGlobal :: String -> UExp ULam :: Ty -> UExp -> UExp UApp :: UExp -> UExp -> UExp UArith :: UExp -> UArithOp -> UExp -> UExp UCond :: UExp -> UExp -> UExp -> UExp UFix :: UExp -> UExp UIntE :: Int -> UExp UBoolE :: Bool -> UExp instance PrettyExp UExp instance Pretty UExp -- | Defines the Glambda Statement type, which can either be a bare -- expression or a global variable assignment. module Language.Glambda.Statement -- | A statement can either be a bare expression, which will be evaluated, -- or an assignment to a global variable. data Statement BareExp :: UExp -> Statement NewGlobal :: String -> UExp -> Statement instance Pretty Statement -- | Parses tokens into the un-type-checked AST. Parsing, in -- glambda, also includes name resolution. This all might conceivably be -- done in a later pass, but there doesn't seem to be an incentive to do -- so. module Language.Glambda.Parse -- | Parse a sequence of semicolon-separated statements, aborting with an -- error upon failure parseStmtsG :: [LToken] -> GlamE [Statement] -- | Parse a sequence of semicolon-separated statements parseStmts :: [LToken] -> Either String [Statement] -- | Parse a Statement, aborting with an error upon failure parseStmtG :: [LToken] -> GlamE Statement -- | Parse a UExp, aborting with an error upon failure parseExpG :: [LToken] -> GlamE UExp -- | Parse a Statement parseStmt :: [LToken] -> Either String Statement -- | Parse a UExp parseExp :: [LToken] -> Either String UExp -- | Lexes a Glambda program string into a sequence of tokens module Language.Glambda.Lex -- | Lex some program text into a list of LTokens, aborting upon -- failure lexG :: String -> GlamE [LToken] -- | Lex some program text into a list of LTokens lex :: String -> Either String [LToken] -- | Glambda expression evaluators for checked expressions. module Language.Glambda.Eval -- | Evaluate an expression, using big-step semantics. eval :: Exp [] t -> Val t -- | Step an expression, either to another expression or to a value. step :: Exp [] t -> Either (Exp [] t) (Val t) -- | The glambda typechecker. module Language.Glambda.Check -- | Check the given expression, aborting on type errors. The resulting -- type and checked expression is given to the provided continuation. -- This is parameterized over the choice of monad in order to support -- pure operation during testing. GlamE is the canonical choice -- for the monad. check :: (MonadError Doc m, MonadReader Globals m) => UExp -> (forall t. STy t -> Exp [] t -> m r) -> m r -- | Implements a REPL for glambda. module Language.Glambda.Repl -- | The glamorous Glambda interpreter main :: IO () instance [overlap ok] Pretty a => Reportable a instance [overlap ok] Reportable Globals instance [overlap ok] Reportable () instance [overlap ok] Reportable Doc