systemqfw

system Q F omega elaborator
git clone git://git.rr3.xyz/systemqfw
Log | Files | Refs | Submodules | LICENSE

commit 0ea9e9063f42a26bf96de209911415392f3375c6
parent 4ccc8ed82ddcf5de69f0d2aaeb572b8a01f3b9e4
Author: Robert Russell <robert@rr3.xyz>
Date:   Tue, 27 Aug 2024 18:58:30 -0700

Elaborate types

Diffstat:
ACore.hs | 37+++++++++++++++++++++++++++++++++++++
AMain.hs | 123+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ASurface.hs | 41+++++++++++++++++++++++++++++++++++++++++
Apackage.yaml | 42++++++++++++++++++++++++++++++++++++++++++
Astack.yaml | 5+++++
5 files changed, 248 insertions(+), 0 deletions(-)

diff --git a/Core.hs b/Core.hs @@ -0,0 +1,37 @@ +module Core where +import qualified Surface as S + +newtype TypeIndex = TypeIndex Int deriving Show +newtype TermIndex = TermIndex Int deriving Show + +type Kind = S.Kind + +data Type q + = TypeVar TypeIndex + + | TypeTArrow (Type q) (Type q) + | TypeTForall Kind (Type q) + + | TypeQ q + -- TODO: Internal Mul and Add operations? + + | TypeQTPair (Type q) (Type q) + | TypeQTFst (Type q) + | TypeQTSnd (Type q) + + | TypeArrowAbs (Type q) + | TypeArrowApp (Type q) (Type q) + deriving Show + +data Term q + = TermVar TermIndex + + | TermArrowAbs (Term q) + | TermArrowApp (Term q) (Term q) + + | TermForallAbs (Term q) + | TermForallApp (Term q) (Type q) + deriving Show + +newtype TypeLevel = TypeLevel Int deriving Show +newtype TermLevel = TermLevel Int deriving Show diff --git a/Main.hs b/Main.hs @@ -0,0 +1,123 @@ +module Main where +import Control.Monad +import Control.Monad.Except +import Control.Monad.Reader +import Data.Map.Strict (Map) +import qualified Data.Map.Strict as Map +import Safe (atMay) + +import Algebra +import Ledger (Ledger) +import qualified Ledger as L +import Surface (Kind (..)) +import qualified Surface as S +import qualified Core as C + +-------------------------------------------------------------------------------- +-- Util + +orThrowError :: MonadError e m => Maybe a -> e -> m a +a `orThrowError` e = + case a of + Just x -> return x + Nothing -> throwError e + +mapInsertCons :: Ord k => k -> v -> Map k [v] -> Map k [v] +mapInsertCons k v = + let f (Just vs) = Just (v : vs) + f Nothing = Just [v] + in Map.alter f k + +-------------------------------------------------------------------------------- +-- Context +-- TODO: move to separate module + +data Ctx q = Ctx { + nTypes :: Int, + types :: Map S.TypeName [(C.TypeLevel, Kind)], + nTerms :: Int, + terms :: Map S.TermName [(C.TermLevel, C.Type q)] +} + +ctxEmpty :: Ctx q +ctxEmpty = Ctx 0 Map.empty 0 Map.empty + +ctxBindType :: S.TypeName -> Kind -> Ctx q -> Ctx q +ctxBindType x k ctx = + let lvl = C.TypeLevel ctx.nTypes in + ctx { + nTypes = ctx.nTypes + 1, + types = mapInsertCons x (lvl, k) ctx.types + } + +ctxLookupType :: S.TypeName -> Ctx q -> Maybe (C.TypeLevel, Kind) +ctxLookupType x ctx = do + xBindings <- Map.lookup x ctx.types + xBindings `atMay` 0 + +ctxTypeLevelToIndex :: C.TypeLevel -> Ctx q -> C.TypeIndex +ctxTypeLevelToIndex (C.TypeLevel lvl) ctx = C.TypeIndex (ctx.nTypes - lvl - 1) + +-------------------------------------------------------------------------------- +-- Elaboration + +data Err = Err + +type Elab q a = ReaderT (Ctx q) (Except Err) a + +bindType :: S.TypeName -> Kind -> Elab q a -> Elab q a +bindType x k = local (ctxBindType x k) + +lookupType :: S.TypeName -> Elab q (C.TypeLevel, Kind) +lookupType x = asks (ctxLookupType x) >>= (`orThrowError` Err) -- TODO + +typeLevelToIndex :: C.TypeLevel -> Elab q C.TypeIndex +typeLevelToIndex lvl = asks (ctxTypeLevelToIndex lvl) + +inferType :: S.Type q -> Elab q (C.Type q, Kind) +inferType = \case + S.TypeVar x -> do + (lvl, k) <- lookupType x + idx <- typeLevelToIndex lvl + pure (C.TypeVar idx, k) + S.TypeAnnot a k -> (, k) <$> checkType a k + S.TypeTArrow dom cod -> do + dom' <- checkType dom KindQT + cod' <- checkType cod KindQT + pure (C.TypeTArrow dom' cod', KindT) + S.TypeTForall x k a -> do + a' <- bindType x k $ checkType a KindQT + pure (C.TypeTForall k a', KindT) + S.TypeQ q -> pure (C.TypeQ q, KindQ) + S.TypeQTPair q a -> do + q' <- checkType q KindQ + a' <- checkType a KindT + pure (C.TypeQTPair q' a', KindQT) + S.TypeQTFst qa -> do + qa' <- checkType qa KindQT + pure (C.TypeQTFst qa', KindQ) + S.TypeQTSnd qa -> do + qa' <- checkType qa KindQT + pure (C.TypeQTSnd qa', KindT) + S.TypeArrowAbs _ _ -> throwError Err -- TODO + S.TypeArrowApp fun arg -> do + (fun', k) <- inferType fun + case k of + KindArrow dom cod -> do + arg' <- checkType arg dom + pure (C.TypeArrowApp fun' arg', cod) + _ -> throwError Err -- TODO + +checkType :: S.Type q -> Kind -> Elab q (C.Type q) +checkType a k = case (a, k) of + (S.TypeArrowAbs x body, KindArrow dom cod) -> + bindType x dom $ checkType body cod + (a, k) -> do + (a', k') <- inferType a + unless (k' == k) $ throwError Err -- TODO + pure a' + +-------------------------------------------------------------------------------- + +main :: IO () +main = putStrLn "whoa" diff --git a/Surface.hs b/Surface.hs @@ -0,0 +1,41 @@ +module Surface where +import Data.ByteString (ByteString) + +newtype TypeName = TypeName ByteString deriving (Eq, Ord, Show) +newtype TermName = TermName ByteString deriving (Eq, Ord, Show) + +data Kind + = KindT + | KindQ + | KindQT + | KindArrow Kind Kind + deriving (Eq, Show) + +data Type q + = TypeVar TypeName + | TypeAnnot (Type q) Kind + + | TypeTArrow (Type q) (Type q) + | TypeTForall TypeName Kind (Type q) + + | TypeQ q + -- TODO: Internal Mul and Add operations? + + | TypeQTPair (Type q) (Type q) + | TypeQTFst (Type q) + | TypeQTSnd (Type q) + + | TypeArrowAbs TypeName (Type q) + | TypeArrowApp (Type q) (Type q) + deriving Show + +data Term q + = TermVar TermName + | TermAnnot (Term q) (Type q) + + | TermArrowAbs TermName (Term q) + | TermArrowApp (Term q) (Term q) + + | TermForallAbs TypeName (Term q) + | TermForallApp (Term q) (Type q) + deriving Show diff --git a/package.yaml b/package.yaml @@ -0,0 +1,42 @@ +name: systemqfw +version: 0.1.0.0 +author: "Robert Russell" +license: ISC + +ghc-options: + - -Wall + - -Wno-name-shadowing + - -Wno-missing-signatures + +default-extensions: + - DuplicateRecordFields + - NoFieldSelectors + - OverloadedRecordDot + + - BlockArguments + - LambdaCase + - MultiWayIf + - TupleSections + - OverloadedStrings + + - ScopedTypeVariables + - TypeFamilies + - FlexibleContexts + - TypeOperators + + - FlexibleInstances + - MultiParamTypeClasses + - UndecidableInstances + +dependencies: + - base >= 4.18 && < 5 + - bytestring + - containers + - mtl + - safe + - sparsec + +executables: + systemqfw: + source-dirs: . + main: Main.hs diff --git a/stack.yaml b/stack.yaml @@ -0,0 +1,5 @@ +resolver: lts-22.23 + +packages: + - . + - sparsec