Skip to content

Commit ad073e5

Browse files
committed
wip: scaffolded the error
1 parent 46fe3b9 commit ad073e5

File tree

6 files changed

+114
-69
lines changed

6 files changed

+114
-69
lines changed

lambda-buffers-compiler/lambda-buffers-compiler.cabal

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ test-suite tests
172172
Test.DeriveCheck
173173
Test.KindCheck
174174
Test.KindCheck.Errors
175+
Test.KindCheck.TyClass
175176
Test.LambdaBuffers.Compiler
176177
Test.LambdaBuffers.Compiler.Coverage
177178
Test.LambdaBuffers.Compiler.Mutation

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import LambdaBuffers.Compiler.KindCheck.Inference (protoKind2Kind)
2424
import LambdaBuffers.Compiler.KindCheck.Inference qualified as I
2525
import LambdaBuffers.Compiler.KindCheck.Kind (Kind (KConstraint, KType, KVar, (:->:)))
2626
import LambdaBuffers.Compiler.KindCheck.Type (
27-
Variable (QualifiedConstraint, QualifiedTyRef, TyVar),
27+
Variable (QualifiedTyClassRef, QualifiedTyRef, TyVar),
2828
ftrISOqtr,
2929
ltrISOqtr,
3030
qTyRef'moduleName,
@@ -136,7 +136,8 @@ runKindCheck = interpret $ \case
136136
CheckClassDefinition modName classDef ctx ->
137137
either (handleErr2 modName classDef) pure $ I.runClassDefCheck ctx modName classDef
138138
where
139-
handleErr2 = undefined
139+
handleErr2 :: forall {b}. PC.ModuleName -> PC.ClassDef -> I.InferErr -> Eff effs b
140+
handleErr2 _ _ _err = error "Throw an error"
140141

141142
handleErr :: forall {b}. PC.ModuleName -> PC.TyDef -> I.InferErr -> Eff effs b
142143
handleErr modName td = \case
@@ -155,7 +156,7 @@ runKindCheck = interpret $ \case
155156
throwError . PC.CompKindCheckError $ PC.UnboundTyRefError td foreignRef modName
156157
TyVar tv ->
157158
throwError . PC.CompKindCheckError $ PC.UnboundTyVarError td (PC.TyVar tv) modName
158-
QualifiedConstraint _ -> error "NOTE(cstml): FIXME."
159+
QualifiedTyClassRef _ -> error "NOTE(cstml): FIXME."
159160
I.InferUnifyTermErr (I.Constraint (k1, k2)) -> do
160161
err <- PC.IncorrectApplicationError td <$> kind2ProtoKind k1 <*> kind2ProtoKind k2 <*> pure modName
161162
throwError $ PC.CompKindCheckError err

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

Lines changed: 42 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ module LambdaBuffers.Compiler.KindCheck.Inference (
1212
Context (..),
1313
Atom,
1414
Type (..),
15-
DeriveM,
1615
DeriveEff,
1716
InferErr (..),
1817
Constraint (..),
@@ -31,30 +30,33 @@ import Control.Monad.Freer.State (State, evalState, get, put)
3130
import Control.Monad.Freer.Writer (Writer, runWriter, tell)
3231
import Data.Foldable (foldrM, traverse_)
3332
import Data.Map qualified as M
33+
import Data.Text (Text)
3434
import Data.Text qualified as T
3535
import LambdaBuffers.Compiler.KindCheck.Derivation (
3636
Context (Context),
3737
Derivation (Abstraction, Application, Axiom, Implication),
3838
Judgement (Judgement),
3939
addContext,
40-
context,
4140
d'kind,
4241
d'type,
42+
getAllContext,
4343
)
4444
import LambdaBuffers.Compiler.KindCheck.Kind (Atom, Kind (KConstraint, KType, KVar, (:->:)))
4545
import LambdaBuffers.Compiler.KindCheck.Type (
4646
Type (Abs, App, Constructor, Opaque, Product, Sum, UnitT, Var, VoidT),
47-
Variable (QualifiedTyRef, TyVar),
47+
Variable (QualifiedTyClassRef, QualifiedTyRef, TyVar),
48+
fcrISOqtcr,
4849
ftrISOqtr,
50+
lcrISOftcr,
51+
lcrISOqtcr,
4952
ltrISOqtr,
5053
)
51-
import LambdaBuffers.Compiler.ProtoCompat.InfoLess (InfoLess, mkInfoLess)
54+
import LambdaBuffers.Compiler.ProtoCompat.InfoLess (mkInfoLess)
5255
import LambdaBuffers.Compiler.ProtoCompat.Types qualified as PC
5356
import Prettyprinter (Pretty (pretty), (<+>))
5457

55-
-- | Utility to unify the two.
56-
getAllContext :: Context -> M.Map (InfoLess Variable) Kind
57-
getAllContext c = c ^. context <> c ^. addContext
58+
--------------------------------------------------------------------------------
59+
-- Types
5860

5961
data InferErr
6062
= InferUnboundTermErr Variable
@@ -74,30 +76,20 @@ newtype Substitution = Substitution {getSubstitution :: (Atom, Kind)}
7476
instance Pretty Substitution where
7577
pretty (Substitution (a, k)) = pretty a <+> "" <+> pretty k
7678

77-
newtype DerivationContext = DC
78-
{ _startAtom :: Atom
79-
}
79+
--------------------------------------------------------------------------------
80+
-- Effects
8081

81-
type DeriveEff = '[State Context, State DerivationContext, State [Constraint], Error InferErr]
82+
newtype DerivationContext = DC {_startAtom :: Atom}
8283

83-
type DeriveM a = Eff DeriveEff a
84+
type DeriveEff =
85+
'[Reader Context, Reader PC.ModuleName, State DerivationContext, Writer [Constraint], Error InferErr]
8486

85-
type Derive a =
86-
forall effs.
87-
Members
88-
'[ Reader Context
89-
, Reader PC.ModuleName
90-
, State DerivationContext
91-
, Writer [Constraint]
92-
, Error InferErr
93-
]
94-
effs =>
95-
Eff effs a
87+
type Derive a = forall effs. Members DeriveEff effs => Eff effs a
9688

9789
--------------------------------------------------------------------------------
9890
-- Runners
9991

100-
-- | Run derivation builder - not unified yet.
92+
-- | Run Derive Monad - not unified.
10193
runDerive :: Context -> PC.ModuleName -> Derive a -> Either InferErr (a, [Constraint])
10294
runDerive ctx localMod =
10395
run . runError . runWriter . evalState (DC startAtom) . runReader ctx . runReader localMod
@@ -261,17 +253,24 @@ deriveClassDef :: PC.ClassDef -> Derive ()
261253
deriveClassDef classDef = traverse_ deriveConstraint (classDef ^. #supers)
262254

263255
deriveConstraint :: PC.Constraint -> Derive Derivation
264-
deriveConstraint _constraint = do
265-
-- ctx <- ask
266-
-- FIXME
267-
-- k2 <- getKind (ConstraintT undefined)
268-
-- argD <- deriveTy (constraint ^. #argument)
269-
pure $ error "NOTE(cstml): fixme."
270-
271-
-- Application
272-
-- (Judgement ctx (App (Var (QualifiedConstraint undefined))) k2)
273-
-- (Judgement ctx (App (Var (QualifiedConstraint undefined) k2)))
274-
-- argD
256+
deriveConstraint constraint = do
257+
mn <- ask
258+
ctx <- ask
259+
let qcr = case constraint ^. #classRef of
260+
PC.LocalCI lcr -> QualifiedTyClassRef . withIso lcrISOqtcr const $ (lcr, mn)
261+
PC.ForeignCI fcr -> QualifiedTyClassRef . withIso fcrISOqtcr const $ fcr
262+
dConstraint <- deriveVar qcr
263+
argD <- deriveTy (constraint ^. #argument)
264+
let argTy = argD ^. d'type
265+
freshK <- KVar <$> fresh
266+
tell [Constraint (dConstraint ^. d'kind, (argD ^. d'kind) :->: freshK)]
267+
pure $ Application (Judgement ctx (App (dConstraint ^. d'type) argTy) freshK) dConstraint argD
268+
269+
deriveVar :: Variable -> Derive Derivation
270+
deriveVar v = do
271+
ctx <- ask
272+
k <- getKind v
273+
pure . Axiom $ Judgement ctx (Var v) k
275274

276275
--------------------------------------------------------------------------------
277276
--
@@ -348,19 +347,13 @@ unify (constraint@(Constraint (l, r)) : xs) = case l of
348347

349348
appearsErr :: forall eff a. Member (Error InferErr) eff => Atom -> Kind -> Eff eff a
350349
appearsErr var ty =
351-
throwError $
352-
InferRecursiveSubstitutionErr $
353-
mconcat
354-
[ "Cannot unify: "
355-
, T.pack . show . pretty $ var
356-
, " with "
357-
, T.pack . show . pretty $ ty
358-
, ". "
359-
, T.pack . show . pretty $ var
360-
, " appears in: "
361-
, T.pack . show . pretty $ ty
362-
, "."
363-
]
350+
throwError
351+
$ InferRecursiveSubstitutionErr
352+
. mconcat
353+
$ ["Cannot unify: ", p var, " with ", p ty, ". ", p var, " appears in: ", p ty, "."]
354+
where
355+
p :: forall b. Pretty b => b -> Text
356+
p = T.pack . show . pretty
364357

365358
appearsIn a ty = a `elem` getVariables ty
366359

@@ -393,8 +386,6 @@ substitute s d = case d of
393386

394387
applySubstitutionCtx subs ctx = ctx & addContext %~ fmap (applySubstitution subs)
395388

396-
-- FIXME(cstml) not avoiding any clashes
397-
398389
-- | Fresh startAtom
399390
startAtom :: Atom
400391
startAtom = 0
@@ -405,5 +396,5 @@ protoKind2Kind = \case
405396
PC.Kind k -> case k of
406397
PC.KindArrow k1 k2 -> protoKind2Kind k1 :->: protoKind2Kind k2
407398
PC.KindRef PC.KType -> KType
408-
PC.KindRef PC.KUnspecified -> KType -- unspecified kinds get defaulted
399+
PC.KindRef PC.KUnspecified -> KType
409400
PC.KindRef PC.KConstraint -> KConstraint

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

Lines changed: 59 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,20 @@ module LambdaBuffers.Compiler.KindCheck.Type (
66
tyUnit,
77
tySum,
88
tyVoid,
9-
Variable (TyVar, QualifiedTyRef, QualifiedConstraint),
9+
Variable (TyVar, QualifiedTyRef, QualifiedTyClassRef),
1010
QualifiedTyRefName (..),
11-
QualifiedClassName (..),
11+
QualifiedTyClassRefName (..),
1212
qTyRef'tyName,
1313
qTyRef'moduleName,
1414
qTyRef'sourceInfo,
15+
16+
-- * Isomorphisms.
1517
ltrISOqtr,
1618
ftrISOqtr,
1719
ltrISOftr,
20+
fcrISOqtcr,
21+
lcrISOftcr,
22+
lcrISOqtcr,
1823
) where
1924

2025
import Control.Lens (iso, makeLenses, withIso, (^.))
@@ -25,8 +30,7 @@ import LambdaBuffers.Compiler.ProtoCompat.InfoLess (InfoLess, InfoLessC, withInf
2530
import LambdaBuffers.Compiler.ProtoCompat.Types qualified as PC
2631
import Prettyprinter (Pretty (pretty), viaShow)
2732

28-
-- NOTE(cstml): Let's remove the Arbitrary instances and replaces them with
29-
-- Gens.
33+
-- NOTE(cstml): Remove the Arbitrary instances and replaces them with Gens.
3034

3135
data QualifiedTyRefName = QualifiedTyRefName
3236
{ _qTyRef'tyName :: PC.TyName
@@ -39,13 +43,27 @@ instance InfoLessC QualifiedTyRefName
3943

4044
makeLenses ''QualifiedTyRefName
4145

46+
data QualifiedTyClassRefName = QualifiedTyClassRefName
47+
{ _qTyClass'className :: PC.ClassName
48+
, _qTyClass'moduleName :: PC.ModuleName
49+
, _qTyClass'sourceInfo :: PC.SourceInfo
50+
}
51+
deriving stock (Eq, Ord, Show, Generic)
52+
deriving anyclass (SOP.Generic)
53+
instance InfoLessC QualifiedTyClassRefName
54+
55+
makeLenses ''QualifiedTyClassRefName
56+
57+
instance Pretty (InfoLess Variable) where
58+
pretty x = withInfoLess x pretty
59+
4260
{- | All TyRefs and ClassNames are fully qualified. The context determines if
4361
they are local or not.
4462
-}
4563
data Variable
4664
= QualifiedTyRef QualifiedTyRefName
65+
| QualifiedTyClassRef QualifiedTyClassRefName
4766
| TyVar PC.VarName
48-
| QualifiedConstraint QualifiedClassName
4967
deriving stock (Eq, Show, Ord, Generic)
5068
deriving anyclass (SOP.Generic)
5169

@@ -54,14 +72,6 @@ instance InfoLessC Variable
5472
instance Pretty Variable where
5573
pretty = viaShow
5674

57-
data QualifiedClassName = QualifiedClassName PC.ClassName PC.ModuleName
58-
deriving stock (Eq, Ord, Show, Generic)
59-
deriving anyclass (SOP.Generic)
60-
instance InfoLessC QualifiedClassName
61-
62-
instance Pretty (InfoLess Variable) where
63-
pretty x = withInfoLess x pretty
64-
6575
data Type
6676
= Abs PC.TyAbs
6777
| App Type Type
@@ -89,7 +99,9 @@ tyVoid = VoidT
8999
instance Pretty Type where
90100
pretty = viaShow
91101

92-
-- | (PC.LocalRef, PC.ModuleName) isomorphism with QualifiedTyRefName.
102+
--------------------------------------------------------------------------------
103+
-- Qualified TyRef ISOs.
104+
93105
ltrISOqtr :: Iso' (PC.LocalRef, PC.ModuleName) QualifiedTyRefName
94106
ltrISOqtr = iso goRight goLeft
95107
where
@@ -101,7 +113,6 @@ ltrISOqtr = iso goRight goLeft
101113
, qtr ^. qTyRef'moduleName
102114
)
103115

104-
-- | LocalTyRef isomorphism with ForeignTyRef
105116
ltrISOftr :: Iso' (PC.LocalRef, PC.ModuleName) PC.ForeignRef
106117
ltrISOftr = iso goRight goLeft
107118
where
@@ -119,3 +130,36 @@ ftrISOqtr = iso goRight goLeft
119130

120131
goLeft :: QualifiedTyRefName -> PC.ForeignRef
121132
goLeft = withIso ltrISOftr $ \l2f _ -> withIso ltrISOqtr $ \_ q2l -> l2f . q2l
133+
134+
--------------------------------------------------------------------------------
135+
-- Qualified TyClass Name ISOs.
136+
137+
lcrISOqtcr :: Iso' (PC.LocalClassRef, PC.ModuleName) QualifiedTyClassRefName
138+
lcrISOqtcr = iso goRight goLeft
139+
where
140+
goRight :: (PC.LocalClassRef, PC.ModuleName) -> QualifiedTyClassRefName
141+
goRight (lcr, mn) = QualifiedTyClassRefName (lcr ^. #className) mn (lcr ^. #sourceInfo)
142+
143+
goLeft :: QualifiedTyClassRefName -> (PC.LocalClassRef, PC.ModuleName)
144+
goLeft qtcn =
145+
( PC.LocalClassRef (qtcn ^. qTyClass'className) (qtcn ^. qTyClass'sourceInfo)
146+
, qtcn ^. qTyClass'moduleName
147+
)
148+
149+
lcrISOftcr :: Iso' (PC.LocalClassRef, PC.ModuleName) PC.ForeignClassRef
150+
lcrISOftcr = iso goRight goLeft
151+
where
152+
goRight :: (PC.LocalClassRef, PC.ModuleName) -> PC.ForeignClassRef
153+
goRight (lr, mn) = PC.ForeignClassRef (lr ^. #className) mn (lr ^. #sourceInfo)
154+
155+
goLeft :: PC.ForeignClassRef -> (PC.LocalClassRef, PC.ModuleName)
156+
goLeft fr = (PC.LocalClassRef (fr ^. #className) (fr ^. #sourceInfo), fr ^. #moduleName)
157+
158+
fcrISOqtcr :: Iso' PC.ForeignClassRef QualifiedTyClassRefName
159+
fcrISOqtcr = iso goRight goLeft
160+
where
161+
goRight :: PC.ForeignClassRef -> QualifiedTyClassRefName
162+
goRight = withIso lcrISOftcr $ \_ f2l -> withIso lcrISOqtcr $ \l2q _ -> l2q . f2l
163+
164+
goLeft :: QualifiedTyClassRefName -> PC.ForeignClassRef
165+
goLeft = withIso lcrISOftcr $ \l2f _ -> withIso lcrISOqtcr $ \_ q2l -> l2f . q2l

lambda-buffers-compiler/test/Test/KindCheck.hs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import LambdaBuffers.Compiler.KindCheck (
77

88
import LambdaBuffers.Compiler.KindCheck.Kind (Kind (KType, (:->:)))
99
import Test.KindCheck.Errors (testGKindCheckErrors)
10+
import Test.KindCheck.TyClass qualified as KCTC
1011
import Test.QuickCheck (Arbitrary (arbitrary), forAll, (===))
1112
import Test.Tasty (TestTree, testGroup)
1213
import Test.Tasty.HUnit (assertBool, testCase, (@?=))
@@ -29,6 +30,7 @@ test =
2930
[ testCheck
3031
, testFolds
3132
, testGKindCheckErrors
33+
, KCTC.test
3234
]
3335

3436
--------------------------------------------------------------------------------
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
module Test.KindCheck.TyClass (test) where
2+
3+
import Test.Tasty (TestTree, testGroup)
4+
5+
test :: TestTree
6+
test = testGroup "KC Class definitions Error Group." []

0 commit comments

Comments
 (0)