Skip to content

Commit 44044d5

Browse files
committed
Cleaned up PR in accordance w/ Drazen's comments (minus module renaming, doing that last)
1 parent 07337e0 commit 44044d5

File tree

7 files changed

+93
-144
lines changed

7 files changed

+93
-144
lines changed

lambda-buffers-compiler/src/LambdaBuffers/Compiler/TypeClass/Pat.hs

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,6 @@ data Pat
7171
DecP Pat Pat Pat
7272
deriving stock (Show, Eq, Ord)
7373

74-
-- infixr 5 :*
75-
7674
{- Utility functions. Turn a list of types into a product/record/sum type.
7775
-}
7876
toProdP :: [Pat] -> Pat
@@ -166,13 +164,6 @@ expList = \case
166164
p1 `ConsE` p2 -> (p1 :) <$> expList p2
167165
_ -> Nothing
168166

169-
{- This is used as a predicate to filter instances or Gens which are structurally compatible
170-
with the argument type.
171-
The first argument is the inner Pat from an instance head or Gen.
172-
The second argument is the Pat representation of a type that we want to derive an instance / generate code for.
173-
NOTE: Is not bidirectional! The first Pat has to be more general than the first
174-
(more specifically: The second Pat should be a substitution instance of the first)
175-
-}
176167
matches :: Pat -> Exp -> Bool
177168
matches (LitP l1) (LitE l2) = l1 == l2
178169
matches (VarP _) _ = True

lambda-buffers-compiler/src/LambdaBuffers/Compiler/TypeClass/Solve.hs

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -44,16 +44,13 @@ inst = subV M.empty
4444
are replaced in the instance superclasses as well (if they occur there).
4545
-}
4646
subst :: Rule Pat -> Exp -> Rule Exp
47-
subst cst@(C _ t :<= _) ty = fmap (go (getSubs t ty)) cst
48-
where
49-
go :: [(Text, Exp)] -> Pat -> Exp
50-
go subs = subV (M.fromList subs)
47+
subst cst@(C _ t :<= _) ty = fmap (subV (getSubs t ty)) cst
5148

5249
{- Given two patterns (which are hopefully structurally similar), gather a list of all substitutions
5350
from the PatVars in the first argument to the concrete types (hopefully!) in the second argument
5451
-}
55-
getSubs :: Pat -> Exp -> [(Text, Exp)] -- should be a set, whatever
56-
getSubs (VarP s) t = [(s, t)]
52+
getSubs :: Pat -> Exp -> M.Map Text Exp -- should be a set, whatever
53+
getSubs (VarP s) t = M.fromList [(s, t)]
5754
getSubs (ConsP x xs) (ConsE x' xs') = getSubs x x' <> getSubs xs xs'
5855
getSubs (LabelP l t) (LabelE l' t') = getSubs l l' <> getSubs t t'
5956
getSubs (ProdP xs) (ProdE xs') = getSubs xs xs'
@@ -62,22 +59,23 @@ getSubs (SumP xs) (SumE xs') = getSubs xs xs'
6259
getSubs (AppP t1 t2) (AppE t1' t2') = getSubs t1 t1' <> getSubs t2 t2'
6360
getSubs (RefP n t) (RefE n' t') = getSubs n n' <> getSubs t t'
6461
getSubs (DecP a b c) (DecE a' b' c') = getSubs a a' <> getSubs b b' <> getSubs c c'
65-
getSubs _ _ = []
62+
getSubs _ _ = M.empty
6663

6764
-- NoMatch isn't fatal but OverlappingMatches is (i.e. we need to stop when we encounter it)
68-
data MatchError
65+
data MatchResult
6966
= NoMatch
7067
| OverlappingMatches [Rule Pat]
68+
| MatchFound (Rule Pat)
7169

7270
-- for SolveM, since we catch NoMatch
7371
data Overlap = Overlap (Constraint Exp) [Rule Pat]
7472
deriving stock (Show, Eq)
7573

76-
selectMatchingInstance :: Exp -> Class -> [Rule Pat] -> Either MatchError (Rule Pat)
74+
selectMatchingInstance :: Exp -> Class -> [Rule Pat] -> MatchResult
7775
selectMatchingInstance e c rs = case filter matchPatAndClass rs of
78-
[] -> Left NoMatch
79-
[r] -> Right r
80-
overlaps -> Left $ OverlappingMatches overlaps
76+
[] -> NoMatch
77+
[r] -> MatchFound r
78+
overlaps -> OverlappingMatches overlaps
8179
where
8280
matchPatAndClass :: Rule Pat -> Bool
8381
matchPatAndClass r =
@@ -103,10 +101,9 @@ solveM (C _ (LitE (TyVar _))) = pure ()
103101
solveM cst@(C c pat) =
104102
ask >>= \inScope ->
105103
case selectMatchingInstance pat c inScope of
106-
Left e -> case e of
107-
NoMatch -> tell $ S.singleton cst
108-
OverlappingMatches olps -> throwError $ Overlap cst olps
109-
Right rule -> case subst rule pat of
104+
NoMatch -> tell $ S.singleton cst
105+
OverlappingMatches olps -> throwError $ Overlap cst olps
106+
MatchFound rule -> case subst rule pat of
110107
C _ p :<= [] -> solveClassesFor p (csupers c)
111108
C _ _ :<= is -> do
112109
traverse_ solveM is

lambda-buffers-compiler/src/LambdaBuffers/Compiler/TypeClass/Utils.hs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ data TypeClassError
7979
| ClassNotFoundInModule Text [Text]
8080
| LocalTyRefNotFound T.Text P.ModuleName
8181
| SuperclassCycleDetected [[FQClassName]]
82-
| CouldntSolveConstraints P.ModuleName [Constraint Exp] Instance
82+
| FailedToSolveConstraints P.ModuleName [Constraint Exp] Instance
8383
| MalformedTyDef P.ModuleName Exp
8484
| BadInstance BasicConditionViolation
8585
deriving stock (Show, Eq, Generic)
@@ -114,7 +114,7 @@ instance Pretty TypeClassError where
114114
. map (hcat . punctuate " => " . map pretty)
115115
$ crs
116116
)
117-
CouldntSolveConstraints mn cs i ->
117+
FailedToSolveConstraints mn cs i ->
118118
"Error: Could not derive instance:"
119119
<+> pointies (pretty i)
120120
<> line

lambda-buffers-compiler/src/LambdaBuffers/Compiler/TypeClass/Validate.hs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,14 @@ constraintClass (C c _) = c
6464
-- half of Haskell's orphan instances rule. We could relax that in various ways
6565
-- but it would require reworking a lot of the utilities above.
6666
checkDerive :: P.ModuleName -> ModuleBuilder -> Rule Pat -> Either TypeClassError [Constraint Exp]
67-
checkDerive mn mb i = concat <$> (traverse solveRef =<< catchOverlap (solve assumptions c))
67+
checkDerive mn mb i = concat <$> secondPass
6868
where
69+
secondPass :: Either TypeClassError [[Constraint Exp]]
70+
secondPass = traverse solveRef =<< firstPass
71+
72+
firstPass :: Either TypeClassError [Constraint Exp]
73+
firstPass = catchOverlap (solve assumptions c)
74+
6975
catchOverlap :: Either Overlap a -> Either TypeClassError a
7076
catchOverlap = either (Left . BadInstance . OverlapDetected) pure
7177

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import LambdaBuffers.Compiler.TypeClass.Pretty (spaced, (<//>))
2323
import LambdaBuffers.Compiler.TypeClass.Utils (
2424
Instance,
2525
ModuleBuilder (mbInstances),
26-
TypeClassError (CouldntSolveConstraints),
26+
TypeClassError (FailedToSolveConstraints),
2727
checkInstance,
2828
mkBuilders,
2929
)
@@ -89,7 +89,7 @@ runDeriveCheck mn mb = mconcat <$> traverse go (S.toList $ mbInstances mb)
8989
>> checkDerive mn mb i
9090
>>= \case
9191
[] -> pure ()
92-
xs -> Left $ CouldntSolveConstraints mn xs i
92+
xs -> Left $ FailedToSolveConstraints mn xs i
9393

9494
-- ModuleBuilder is suitable codegen input,
9595
-- and is (relatively) computationally expensive to

0 commit comments

Comments
 (0)