Skip to content

Commit 46fe3b9

Browse files
committed
update: some minor refactoring
1 parent 231d81f commit 46fe3b9

File tree

8 files changed

+378
-282
lines changed

8 files changed

+378
-282
lines changed

lambda-buffers-compiler/src/LambdaBuffers/Compiler/KindCheck.hs

Lines changed: 86 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ module LambdaBuffers.Compiler.KindCheck (
99
foldWithArrowToType,
1010
) where
1111

12-
import Control.Lens (Getter, to, view, (&), (.~), (^.))
12+
import Control.Lens (view, (&), (.~), (^.))
13+
import Control.Lens.Iso (withIso)
1314
import Control.Monad (void)
1415
import Control.Monad.Freer (Eff, Member, Members, interpret, reinterpret, run)
1516
import Control.Monad.Freer.Error (Error, runError, throwError)
@@ -18,11 +19,16 @@ import Control.Monad.Freer.TH (makeEffect)
1819
import Data.Default (Default (def))
1920
import Data.Foldable (Foldable (toList), traverse_)
2021
import Data.Map qualified as M
21-
22-
import LambdaBuffers.Compiler.KindCheck.Derivation (Context, context)
22+
import LambdaBuffers.Compiler.KindCheck.Derivation (Context, constraintContext, context)
23+
import LambdaBuffers.Compiler.KindCheck.Inference (protoKind2Kind)
2324
import LambdaBuffers.Compiler.KindCheck.Inference qualified as I
24-
import LambdaBuffers.Compiler.KindCheck.Kind (Kind (KType, (:->:)), kind2ProtoKind)
25-
import LambdaBuffers.Compiler.KindCheck.Type (Variable (QualifiedTyRef, TyVar))
25+
import LambdaBuffers.Compiler.KindCheck.Kind (Kind (KConstraint, KType, KVar, (:->:)))
26+
import LambdaBuffers.Compiler.KindCheck.Type (
27+
Variable (QualifiedConstraint, QualifiedTyRef, TyVar),
28+
ftrISOqtr,
29+
ltrISOqtr,
30+
qTyRef'moduleName,
31+
)
2632
import LambdaBuffers.Compiler.ProtoCompat.InfoLess (InfoLess, mkInfoLess)
2733
import LambdaBuffers.Compiler.ProtoCompat.Types qualified as PC
2834

@@ -50,18 +56,20 @@ makeEffect ''GlobalCheck
5056
-- | Interactions that happen at the level of the
5157
data ModuleCheck a where -- Module
5258
KCTypeDefinition :: PC.ModuleName -> Context -> PC.TyDef -> ModuleCheck Kind
59+
KCClassInstance :: PC.ModuleName -> Context -> PC.ClassDef -> ModuleCheck ()
5360

54-
-- NOTE(cstml & gnumonik): Lets reach consensus on these - Note(1).
55-
-- KCClassInstance :: Context -> P.InstanceClause -> ModuleCheck ()
5661
-- KCClass :: Context -> P.ClassDef -> ModuleCheck ()
5762

5863
makeEffect ''ModuleCheck
5964

6065
data KindCheck a where
6166
GetSpecifiedKind :: PC.ModuleName -> PC.TyDef -> KindCheck Kind
6267
InferTypeKind :: PC.ModuleName -> PC.TyDef -> Context -> Kind -> KindCheck Kind
68+
CheckClassDefinition :: PC.ModuleName -> PC.ClassDef -> Context -> KindCheck ()
6369
CheckKindConsistency :: PC.ModuleName -> PC.TyDef -> Context -> Kind -> KindCheck Kind
6470

71+
-- CheckClassInstance :: PC.ModuleName -> KindCheck Kind
72+
6573
makeEffect ''KindCheck
6674

6775
--------------------------------------------------------------------------------
@@ -113,57 +121,48 @@ localStrategy = reinterpret $ \case
113121
desiredK <- getSpecifiedKind modName tyDef
114122
k <- inferTypeKind modName tyDef ctx desiredK
115123
checkKindConsistency modName tyDef ctx k
124+
KCClassInstance modName ctx classDef -> do
125+
_ <- checkClassDefinition modName classDef ctx
126+
pure ()
116127

117128
runKindCheck :: forall effs {a}. Member Err effs => Eff (KindCheck ': effs) a -> Eff effs a
118129
runKindCheck = interpret $ \case
119-
InferTypeKind modName tyDef ctx k ->
120-
either (handleErr modName tyDef) pure $ I.infer ctx tyDef k modName
130+
InferTypeKind modName tyDef ctx _k ->
131+
either (handleErr modName tyDef) pure $ I.infer ctx tyDef modName
121132
CheckKindConsistency modName tyDef ctx k ->
122133
runReader modName $ resolveKindConsistency tyDef ctx k
123134
GetSpecifiedKind modName tyDef ->
124135
fmap snd $ runReader modName $ tyDef2NameAndKind tyDef
136+
CheckClassDefinition modName classDef ctx ->
137+
either (handleErr2 modName classDef) pure $ I.runClassDefCheck ctx modName classDef
125138
where
139+
handleErr2 = undefined
140+
126141
handleErr :: forall {b}. PC.ModuleName -> PC.TyDef -> I.InferErr -> Eff effs b
127142
handleErr modName td = \case
128-
I.InferUnboundTermErr uA -> do
129-
case uA of
130-
QualifiedTyRef fr ->
131-
if (fr ^. #moduleName) == modName
132-
then -- We're looking at the local module.
133-
134-
throwError
135-
. PC.CompKindCheckError
136-
$ PC.UnboundTyRefError td (PC.LocalI $ fr ^. foreignRef2LocalRef) modName
137-
else -- We're looking at a foreign module.
138-
139-
throwError
140-
. PC.CompKindCheckError
141-
$ PC.UnboundTyRefError td (PC.ForeignI fr) modName
143+
I.InferUnboundTermErr ut ->
144+
case ut of
145+
QualifiedTyRef qtr -> do
146+
if qtr ^. qTyRef'moduleName == modName
147+
then do
148+
-- We're looking at the local module.
149+
let localRef = PC.LocalI . fst . withIso ltrISOqtr (\_ f -> f) $ qtr
150+
let err = PC.UnboundTyRefError td localRef modName
151+
throwError . PC.CompKindCheckError $ err
152+
else do
153+
-- We're looking at a foreign module.
154+
let foreignRef = PC.ForeignI . withIso ftrISOqtr (\_ f -> f) $ qtr
155+
throwError . PC.CompKindCheckError $ PC.UnboundTyRefError td foreignRef modName
142156
TyVar tv ->
143-
throwError
144-
. PC.CompKindCheckError
145-
$ PC.UnboundTyVarError td (PC.TyVar tv) modName
146-
I.InferUnifyTermErr (I.Constraint (k1, k2)) ->
147-
throwError
148-
. PC.CompKindCheckError
149-
$ PC.IncorrectApplicationError td (kind2ProtoKind k1) (kind2ProtoKind k2) modName
157+
throwError . PC.CompKindCheckError $ PC.UnboundTyVarError td (PC.TyVar tv) modName
158+
QualifiedConstraint _ -> error "NOTE(cstml): FIXME."
159+
I.InferUnifyTermErr (I.Constraint (k1, k2)) -> do
160+
err <- PC.IncorrectApplicationError td <$> kind2ProtoKind k1 <*> kind2ProtoKind k2 <*> pure modName
161+
throwError $ PC.CompKindCheckError err
150162
I.InferRecursiveSubstitutionErr _ ->
151-
throwError
152-
. PC.CompKindCheckError
153-
$ PC.RecursiveKindError td modName
163+
throwError . PC.CompKindCheckError $ PC.RecursiveKindError td modName
154164
I.InferImpossibleErr t ->
155-
throwError $
156-
PC.InternalError t
157-
158-
foreignRef2LocalRef :: Getter PC.ForeignRef PC.LocalRef
159-
foreignRef2LocalRef =
160-
to
161-
( \fr ->
162-
PC.LocalRef
163-
{ tyName = fr ^. #tyName
164-
, sourceInfo = fr ^. #sourceInfo
165-
}
166-
)
165+
throwError $ PC.InternalError t
167166

168167
--------------------------------------------------------------------------------
169168
-- Resolvers
@@ -183,24 +182,28 @@ resolveKindConsistency tyDef _ctx inferredKind = do
183182
guard t i d
184183
| i == d = pure ()
185184
| otherwise = do
186-
mn <- ask
187-
throwError
188-
. PC.CompKindCheckError
189-
$ PC.InconsistentTypeError t (kind2ProtoKind i) (kind2ProtoKind d) mn
185+
err <- PC.InconsistentTypeError t <$> kind2ProtoKind i <*> kind2ProtoKind d <*> ask
186+
throwError $ PC.CompKindCheckError err
190187

191188
--------------------------------------------------------------------------------
192189
-- Context Creation
193190

194191
-- | Resolver function for the context creation. There is a guarantee from ProtoCompat that the input is sanitised.
195192
resolveCreateContext :: forall effs. PC.CompilerInput -> Eff effs Context
196-
resolveCreateContext ci =
197-
mconcat <$> traverse module2Context (toList $ ci ^. #modules)
193+
resolveCreateContext = fmap mconcat . traverse module2Context . toList . view #modules
198194

199195
module2Context :: forall effs. PC.Module -> Eff effs Context
200196
module2Context m = do
201197
let typeDefinitions = toList $ m ^. #typeDefs
202-
ctxs <- runReader (m ^. #moduleName) $ traverse tyDef2Context typeDefinitions
203-
pure $ mconcat ctxs
198+
let classDefinitions = toList $ m ^. #classDefs
199+
-- Context built from type definitions.
200+
typeDefCtx <- fmap mconcat . runReader (m ^. #moduleName) $ traverse tyDef2Context typeDefinitions
201+
-- Context built from class definitions.
202+
classDefCtx <- fmap mconcat . runReader (m ^. #moduleName) $ traverse classDef2Context classDefinitions
203+
return $ typeDefCtx <> classDefCtx
204+
205+
--------------------------------------------------------------------------------
206+
-- Type Definition Based Context Building.
204207

205208
-- | Creates a Context entry from one type definition.
206209
tyDef2Context ::
@@ -219,19 +222,45 @@ tyDef2NameAndKind ::
219222
Eff effs (InfoLess Variable, Kind)
220223
tyDef2NameAndKind tyDef = do
221224
curModName <- ask
222-
223-
-- InfoLess name - the SourceInfo doesn't matter therefore it is defaulted.
225+
-- InfoLess Qualified name - the SourceInfo doesn't matter therefore it is defaulted.
224226
let name =
225227
QualifiedTyRef
226-
. view (PC.localRef2ForeignRef curModName)
228+
. withIso ltrISOqtr const
229+
. (,curModName)
227230
$ PC.LocalRef (tyDef ^. #tyName) def
228231

229232
k = tyAbsLHS2Kind (tyDef ^. #tyAbs)
230233

231234
pure (mkInfoLess name, k)
232235

233236
tyAbsLHS2Kind :: PC.TyAbs -> Kind
234-
tyAbsLHS2Kind tyAbs = foldWithArrowToType $ pKind2Kind . (\x -> x ^. #argKind) <$> toList (tyAbs ^. #tyArgs)
237+
tyAbsLHS2Kind tyAbs = foldWithArrowToType $ tyArg2Kind <$> toList (tyAbs ^. #tyArgs)
238+
239+
tyArg2Kind :: PC.TyArg -> Kind
240+
tyArg2Kind = protoKind2Kind . view #argKind
241+
242+
--------------------------------------------------------------------------------
243+
-- Class Definition Based Context Building.
244+
245+
--- | Convert from internal Kind to Proto Kind.
246+
kind2ProtoKind :: forall effs. Member Err effs => Kind -> Eff effs PC.Kind
247+
kind2ProtoKind = \case
248+
k1 :->: k2 -> fmap PC.Kind $ PC.KindArrow <$> kind2ProtoKind k1 <*> kind2ProtoKind k2
249+
KType -> pure . PC.Kind . PC.KindRef $ PC.KType
250+
KVar _ -> pure . PC.Kind . PC.KindRef $ PC.KUnspecified -- this shouldn't happen.
251+
KConstraint -> pure . PC.Kind . PC.KindRef $ PC.KConstraint
252+
253+
--------------------------------------------------------------------------------
254+
-- Class Definition Based Context Building.
255+
256+
classDef2Context :: forall effs. PC.ClassDef -> Eff effs Context
257+
classDef2Context cDef = do
258+
let className = mkInfoLess . view #className $ cDef
259+
let classArg = tyArg2Kind . view #classArgs $ cDef
260+
pure $ mempty & constraintContext .~ M.singleton className classArg
261+
262+
--------------------------------------------------------------------------------
263+
-- utilities
235264

236265
{- | Folds kinds and appends them to a Kind result type. In essence creates a
237266
curried function with a Type final kind.
@@ -250,13 +279,3 @@ foldWithArrowToType = foldWithArrowToKind KType
250279

251280
foldWithArrowToKind :: Kind -> [Kind] -> Kind
252281
foldWithArrowToKind = foldr (:->:)
253-
254-
--------------------------------------------------------------------------------
255-
-- To Kind Conversion functions
256-
257-
pKind2Kind :: PC.Kind -> Kind
258-
pKind2Kind k =
259-
case k ^. #kind of
260-
PC.KindRef PC.KType -> KType
261-
PC.KindArrow l r -> pKind2Kind l :->: pKind2Kind r
262-
PC.KindRef PC.KUnspecified -> KType -- (for now) defaulting unspecified kinds to Type

lambda-buffers-compiler/src/LambdaBuffers/Compiler/KindCheck/Derivation.hs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
module LambdaBuffers.Compiler.KindCheck.Derivation (
22
Derivation (Axiom, Abstraction, Application, Implication),
3+
QClassName (QClassName),
34
d'type,
45
d'kind,
56
Judgement (Judgement),
@@ -10,12 +11,15 @@ module LambdaBuffers.Compiler.KindCheck.Derivation (
1011
context,
1112
addContext,
1213
getAllContext,
14+
constraintContext,
1315
) where
1416

1517
import Control.Lens (Lens', lens, makeLenses, (&), (.~), (^.))
18+
import Control.Lens.Operators ((%~))
1619
import Data.Map qualified as M
1720
import LambdaBuffers.Compiler.KindCheck.Kind (Kind)
1821
import LambdaBuffers.Compiler.KindCheck.Type (Type, Variable)
22+
import LambdaBuffers.Compiler.ProtoCompat qualified as PC
1923
import LambdaBuffers.Compiler.ProtoCompat.InfoLess (InfoLess)
2024
import Prettyprinter (
2125
Doc,
@@ -33,9 +37,13 @@ import Prettyprinter (
3337
(<+>),
3438
)
3539

40+
-- | Qualified Class Name.
41+
data QClassName = QClassName
42+
3643
data Context = Context
3744
{ _context :: M.Map (InfoLess Variable) Kind
3845
, _addContext :: M.Map (InfoLess Variable) Kind
46+
, _constraintContext :: M.Map (InfoLess PC.ClassName) Kind
3947
}
4048
deriving stock (Show, Eq)
4149

@@ -50,12 +58,16 @@ instance Pretty Context where
5058
setPretty = hsep . punctuate comma . fmap (\(v, t) -> pretty v <> ":" <+> pretty t)
5159

5260
instance Semigroup Context where
53-
(Context a1 b1) <> (Context a2 b2) = Context (a1 <> a2) (b1 <> b2)
61+
c1 <> c2 =
62+
c1
63+
& context %~ (<> c2 ^. context)
64+
& addContext %~ (<> c2 ^. addContext)
65+
& constraintContext %~ (<> c2 ^. constraintContext)
5466

5567
instance Monoid Context where
56-
mempty = Context mempty mempty
68+
mempty = Context mempty mempty mempty
5769

58-
-- | Utility to unify the two.
70+
-- | Utility to unify the two T.
5971
getAllContext :: Context -> M.Map (InfoLess Variable) Kind
6072
getAllContext c = c ^. context <> c ^. addContext
6173

0 commit comments

Comments
 (0)