on master help sign in
Got folding working
commita81aa0a40844df8afbaa65f4e174a033a0997eee authoriko <ilyakooo0@gmail.com> dateFri 2 Apr 2021, 15:40 (6 years ago) parent74e9304
3 files changed+100−67
package.yaml+4 src/Tix/Typechecker.hs+17−19 src/Tix/Types.hs+79−48
package.yaml+4
@@ -37,6 +37,7 @@ dependencies:
3737 - bytestring
3838 - prettyprinter
3939 - range-set-list
40+ - generic-data
4041
4142library:
4243 source-dirs: src
@@ -89,3 +90,6 @@ default-extensions:
8990 - EmptyCase
9091 - OverloadedLists
9192 - StandaloneDeriving
93+ - DeriveGeneric
94+ - DerivingVia
95+ - RecordWildCards
src/Tix/Typechecker.hs+17−19
@@ -110,13 +110,13 @@ close (Predicate f) =
110110 where
111111 -- State is the sequential number, Reader is the binding context number
112112 close' :: Scheme -> Eff '[State Int, Reader Int, State TDeBruijnMap] Scheme
113− close' x@(NAtomic _) = return x
114113 close' (preds :=> t) =
115114 (:=>) <$> (Preds <$> closePred `traverse` unPreds preds) <*> closeType t
116115
117116 closeType :: NType -> Eff '[State Int, Reader Int, State TDeBruijnMap] NType
118117 closeType = \case
119118 x@(NBruijn _) -> return x
119+ x@(NAtomic _) -> return x
120120 (NTypeVariable tv) | f tv -> NBruijn <$> newbruijn tv
121121 x@(NTypeVariable _) -> return x
122122 (x :-> y) -> bndCtx $ (:->) <$> close' x <*> close' y
@@ -157,6 +157,7 @@ instance Free NType where
157157 free (NAttrSet attrs) = foldMap free . M.elems $ attrs
158158 free (x :-> y) = free x <> free y
159159 free (NBruijn _) = S.empty
160+ free (NAtomic _) = S.empty
160161
161162 sub s r = case r of
162163 NBruijn _ -> r
@@ -164,6 +165,7 @@ instance Free NType where
164165 List x -> List $ sub s x
165166 NAttrSet m -> NAttrSet $ sub s <$> m
166167 x :-> y -> sub s x :-> sub s y
168+ x@(NAtomic _) -> x
167169
168170instance Free Preds where
169171 free (Preds ps) = flip foldMap ps $ \case
@@ -183,18 +185,14 @@ instance Free Preds where
183185 where
184186 sub' t = case sub s (scheme t) of
185187 pp :=> t' -> (pp, t')
186− NAtomic _ -> error "can not be atomic" -- this should not be an 'error'
187188
188189instance Free Scheme where
189190 free (x :=> y) = free x <> free y
190− free (NAtomic _) = S.empty
191191 sub s (x :=> NTypeVariable tv) =
192192 case M.lookup tv $ unSubstitution s of
193193 Nothing -> sub s x :=> NTypeVariable tv
194194 Just (newCs :=> new) -> (sub s x <> newCs) :=> new
195− Just a@(NAtomic _) -> assert (null . unPreds $ x) a
196195 sub s (x :=> y) = sub s x :=> sub s y
197− sub _ x@(NAtomic _) = x
198196
199197instance Free a => Free [a] where
200198 free = foldMap free
@@ -241,7 +239,7 @@ unifyWithPriority ::
241239 UnifyM Substitution
242240unifyWithPriority range (lhs :~ rhs) =
243241 case (lhs, rhs) of
244− (NAtomic x, NAtomic y) | x == y -> return mempty
242+ (_ :=> NAtomic x, _ :=> NAtomic y) | x == y -> return mempty
245243 (xcs :=> NTypeVariable x, ycs :=> NTypeVariable y) -> do
246244 let ((lhsCs, lhs'), (rhsCs, rhs')) =
247245 if y `RS.member` range
@@ -385,7 +383,6 @@ instantiate = evalState M.empty . instantiateScheme
385383 instantiateScheme :: forall. Scheme -> Eff (State (Map DeBruijn TypeVariable) ': effs) Scheme
386384 instantiateScheme (ps :=> t) =
387385 (:=>) <$> (Preds <$> traverse instantiatePred (unPreds ps)) <*> instantiate' t
388− instantiateScheme x@(NAtomic _) = return x
389386
390387 instantiatePred :: forall. Pred -> Eff (State (Map DeBruijn TypeVariable) ': effs) Pred
391388 instantiatePred = \case
@@ -398,6 +395,7 @@ instantiate = evalState M.empty . instantiateScheme
398395 instantiate' (x :-> y) = (:->) <$> instantiateScheme x <*> instantiateScheme y
399396 instantiate' (List x) = List <$> instantiateScheme x
400397 instantiate' (NAttrSet xs) = NAttrSet <$> traverse instantiateScheme xs
398+ instantiate' x@(NAtomic _) = return x
401399
402400 freshInst :: DeBruijn -> Eff (State (Map DeBruijn TypeVariable) ': effs) TypeVariable
403401 freshInst db = do
@@ -410,15 +408,15 @@ instantiate = evalState M.empty . instantiateScheme
410408
411409infer :: NExprLoc -> InferM Scheme
412410infer (Fix (Compose (Ann src x))) = runReader src $ case x of
413− NConstant a -> return . NAtomic $ case a of
411+ NConstant a -> return . scheme . NAtomic $ case a of
414412 NURI {} -> URI
415413 NInt {} -> Integer
416414 NFloat {} -> Float
417415 NBool {} -> Bool
418416 NNull {} -> Null
419− NLiteralPath {} -> return . NAtomic $ Path
420− NEnvPath {} -> return . NAtomic $ Path
421− NStr {} -> return $ NAtomic String
417+ NLiteralPath {} -> return . scheme . NAtomic $ Path
418+ NEnvPath {} -> return . scheme . NAtomic $ Path
419+ NStr {} -> return $ scheme $ NAtomic String
422420 NSym var ->
423421 get @VariableMap
424422 >>= maybe (scheme . NTypeVariable <$> throwSrcTV (UndefinedVariable var)) return . M.lookup var
@@ -436,7 +434,7 @@ infer (Fix (Compose (Ann src x))) = runReader src $ case x of
436434 return t
437435 NUnary NNot y -> do
438436 t <- infer y
439− t ~~ NAtomic Bool
437+ t ~~ scheme (NAtomic Bool)
440438 return t
441439 NBinary NUpdate lhs rhs -> do
442440 lhsT <- infer lhs
@@ -515,7 +513,7 @@ infer (Fix (Compose (Ann src x))) = runReader src $ case x of
515513 withBindings bindingsT $ infer body
516514 NIf cond t f -> do
517515 condT <- infer cond
518− condT ~~ NAtomic Bool
516+ condT ~~ scheme (NAtomic Bool)
519517 tT <- infer t
520518 fT <- infer f
521519 tT ~~ fT
@@ -541,7 +539,7 @@ infer (Fix (Compose (Ann src x))) = runReader src $ case x of
541539 return M.empty
542540 NAssert cond body -> do
543541 condT <- infer cond
544− condT ~~ NAtomic Bool
542+ condT ~~ scheme (NAtomic Bool)
545543 infer body
546544 NSynHole _ -> scheme . NTypeVariable <$> freshSrc
547545 where
@@ -549,13 +547,13 @@ infer (Fix (Compose (Ann src x))) = runReader src $ case x of
549547 lhst <- infer lhs
550548 rhst <- infer rhs
551549 lhst ~~ rhst
552− return $ NAtomic Bool
550+ return . scheme $ NAtomic Bool
553551 comparison lhs rhs = do
554552 lhst <- infer lhs
555553 rhst <- infer rhs
556554 -- TODO: Infer lhst and rhst are either Integer or Double or String
557555 lhst ~~ rhst
558− return $ NAtomic Bool
556+ return . scheme $ NAtomic Bool
559557 math lhs rhs = do
560558 lhst <- infer lhs
561559 rhst <- infer rhs
@@ -565,9 +563,9 @@ infer (Fix (Compose (Ann src x))) = runReader src $ case x of
565563 logic lhs rhs = do
566564 lhst <- infer lhs
567565 rhst <- infer rhs
568− rhst ~~ NAtomic Bool
569− lhst ~~ NAtomic Bool
570− return $ NAtomic Bool
566+ rhst ~~ scheme (NAtomic Bool)
567+ lhst ~~ scheme (NAtomic Bool)
568+ return . scheme $ NAtomic Bool
571569
572570inferBinding :: [Binding (Fix NExprLocF)] -> InferM' (Map VarName Scheme)
573571inferBinding bindings = do
src/Tix/Types.hs+79−48
@@ -10,10 +10,15 @@ module Tix.Types
1010 (=>>),
1111 (//),
1212 Preds (..),
13+ foldNTypeM,
14+ foldNType,
15+ NTypeFolder (..),
1316 )
1417where
1518
19+import Control.Applicative
1620import Data.Foldable
21+import Data.Functor.Identity
1722import qualified Data.List as L
1823import Data.Map (Map)
1924import qualified Data.Map as M
@@ -23,6 +28,7 @@ import Data.Text (Text)
2328import qualified Data.Text.Lazy as TL
2429import qualified Data.Text.Lazy.Builder as T
2530import GHC.Exts
31+import Generic.Data
2632import Prettyprinter
2733
2834data Pred
@@ -37,13 +43,11 @@ data Pred
3743 | !NType `HasField` !(Text, Scheme)
3844 deriving stock (Eq, Ord, Show)
3945
46+-- this seems bad. It should not drop constraints.
4047(//) :: Scheme -> Scheme -> Scheme -> Pred
4148(//) (_ :=> x) (_ :=> y) (_ :=> z) = Update x y z
42−(//) _ _ _ = error "Bad update operator" -- This should not be an 'error'
4349
44−data Scheme
45− = Preds :=> !NType
46− | NAtomic !AtomicType
50+data Scheme = Preds :=> !NType
4751 deriving stock (Eq, Ord, Show)
4852
4953newtype Preds = Preds {unPreds :: [Pred]}
@@ -52,14 +56,61 @@ newtype Preds = Preds {unPreds :: [Pred]}
5256(=>>) :: Preds -> Scheme -> Scheme
5357[] =>> x = x
5458xs =>> (ys :=> u) = (xs <> ys) :=> u
55−_ =>> (NAtomic _) = error "Can not constrain atomic type"
5659
5760scheme :: NType -> Scheme
5861scheme t = [] :=> t
5962
63+data NTypeFolder a = NTypeFolder
64+ { variableFolder :: TypeVariable -> a,
65+ deBruijnFolder :: DeBruijn -> a,
66+ atomicFolder :: AtomicType -> a,
67+ compositeFolder :: a -> a
68+ }
69+ deriving stock (Generic)
70+ deriving (Semigroup, Monoid) via Generically (NTypeFolder a)
71+
72+class TypeFoldable t where
73+ foldNTypeM :: (Applicative m, Monoid a) => NTypeFolder (m a) -> t -> m a
74+
75+instance TypeFoldable Scheme where
76+ foldNTypeM tf (Preds ps :=> t) = foldA [foldAType tf ps, foldNTypeM tf t]
77+
78+instance TypeFoldable a => TypeFoldable [a] where
79+ foldNTypeM tf = foldAType tf
80+
81+instance TypeFoldable Pred where
82+ foldNTypeM tf (Update x y z) = foldAType tf [x, y, z]
83+ foldNTypeM tf (HasField x (_, z)) = foldA [foldNTypeM tf x, foldNTypeM tf z]
84+
85+instance TypeFoldable NType where
86+ foldNTypeM NTypeFolder {variableFolder = f} (NTypeVariable x) = f x
87+ foldNTypeM NTypeFolder {deBruijnFolder = f} (NBruijn x) = f x
88+ foldNTypeM NTypeFolder {atomicFolder = f} (NAtomic x) = f x
89+ foldNTypeM tf@NTypeFolder {compositeFolder = f} (x :-> y) = f $ foldAType tf [x, y]
90+ foldNTypeM tf@NTypeFolder {compositeFolder = f} (List x) = f $ foldNTypeM tf x
91+ foldNTypeM tf@NTypeFolder {compositeFolder = f} (NAttrSet x) = f $ foldAType tf $ M.elems x
92+
93+foldNType :: (Monoid a, TypeFoldable x) => NTypeFolder a -> x -> a
94+foldNType NTypeFolder {..} = runIdentity . foldNTypeM tf
95+ where
96+ tf =
97+ NTypeFolder
98+ { variableFolder = Identity . variableFolder,
99+ deBruijnFolder = Identity . deBruijnFolder,
100+ atomicFolder = Identity . atomicFolder,
101+ compositeFolder = Identity . compositeFolder . runIdentity
102+ }
103+
104+foldAType :: (Monoid a, Applicative f, TypeFoldable t) => NTypeFolder (f a) -> [t] -> f a
105+foldAType tf ne = foldA $ fmap (foldNTypeM tf) ne
106+
107+foldA :: (Monoid a, Applicative f) => [f a] -> f a
108+foldA = foldr (liftA2 (<>)) (pure mempty)
109+
60110data NType
61111 = NTypeVariable !TypeVariable
62112 | NBruijn !DeBruijn
113+ | NAtomic !AtomicType
63114 | !Scheme :-> !Scheme
64115 | List !Scheme
65116 | NAttrSet !(Map Text Scheme)
@@ -92,9 +143,9 @@ showNType t = TL.toStrict . T.toLazyText $ showNType' 0 t
92143 where
93144 greekVars = M.fromList $ zip (S.toList $ getAllDeBurjins t) variableNames
94145 showNType' :: Int -> Scheme -> T.Builder
95− showNType' _ (NAtomic a) = showAtomicType a
96146 showNType' depth (Preds ps :=> u) =
97147 foralls <> predicates <> case u of
148+ (NAtomic a) -> showAtomicType a
98149 (NBruijn (DeBruijn i j)) -> greekVars M.! DeBruijn (i - depth) j
99150 (NTypeVariable _) -> error "should not have free type variables at this point"
100151 (x :-> y) -> showNextNType' x <> " -> " <> showNextNType' y
@@ -126,55 +177,35 @@ showNType t = TL.toStrict . T.toLazyText $ showNType' 0 t
126177-- (current) binding context.
127178-- So variables that are bound in one of the inner contexts will have a negative
128179-- binding context number.
129−getAllDeBurjins :: Scheme -> Set DeBruijn
130−getAllDeBurjins (NAtomic _) = S.empty
131−getAllDeBurjins (Preds ps :=> t) =
132− foldMap
133− ( \case
134− (Update x y z) ->
135− bndCtx $
136− getAllTypeDeBurjins x <> getAllTypeDeBurjins y <> getAllTypeDeBurjins z
137− (HasField x (_, y)) -> bndCtx $ getAllTypeDeBurjins x <> getAllDeBurjins y
138− )
139− ps
140− <> case t of
141− (NTypeVariable _) -> S.empty
142− (NBruijn x) -> S.singleton x
143− (x :-> y) -> bndCtx $ getAllDeBurjins x <> getAllDeBurjins y
144− (List x) -> bndCtx $ getAllDeBurjins x
145− (NAttrSet xs) -> bndCtx . foldMap getAllDeBurjins . M.elems $ xs
146− where
147− bndCtx = S.mapMonotonic (\(DeBruijn i j) -> DeBruijn (i - 1) j)
148−
149−getAllTypeDeBurjins :: NType -> Set DeBruijn
150−getAllTypeDeBurjins = getAllDeBurjins . scheme
180+getAllDeBurjins :: TypeFoldable x => x -> Set DeBruijn
181+getAllDeBurjins =
182+ foldNType
183+ NTypeFolder
184+ { variableFolder = const S.empty,
185+ deBruijnFolder = S.singleton,
186+ atomicFolder = const S.empty,
187+ compositeFolder = S.mapMonotonic (\(DeBruijn i j) -> DeBruijn (i - 1) j)
188+ }
151189
152190-- | Get all De Bruijn type variables that were bound in the the outermost
153191-- (current) binding context.
154192-- Only returns the second indexes.
155193getDeBurjins :: NType -> Set Int
156−getDeBurjins = getDeBurjins' 0
194+getDeBurjins t = getDeBurjins' t 0
157195
158196-- | Gets all De Bruijn variables with the given binding context offset.
159197-- Only returns the second indexes.
160−getDeBurjins' :: Int -> NType -> Set Int
161−getDeBurjins' _ (NTypeVariable _) = S.empty
162−getDeBurjins' n (NBruijn (DeBruijn m j)) | m == n = S.singleton j
163−getDeBurjins' _ (NBruijn _) = S.empty
164−getDeBurjins' n (x :-> y) = getSchemeDeBurjins' (n + 1) x <> getSchemeDeBurjins' (n + 1) y
165−getDeBurjins' n (List x) = getSchemeDeBurjins' (n + 1) x
166−getDeBurjins' n (NAttrSet xs) = foldMap (getSchemeDeBurjins' (n + 1)) . M.elems $ xs
167−
168−getSchemeDeBurjins' :: Int -> Scheme -> Set Int
169−getSchemeDeBurjins' _ (NAtomic _) = S.empty
170−getSchemeDeBurjins' n (Preds ps :=> t) =
171− getDeBurjins' n t
172− <> foldMap
173− ( \case
174− Update x y z -> getDeBurjins' n x <> getDeBurjins' n y <> getDeBurjins' n z
175− HasField u (_, v) -> getDeBurjins' n u <> getSchemeDeBurjins' n v
176− )
177− ps
198+getDeBurjins' :: TypeFoldable x => x -> Int -> Set Int
199+getDeBurjins' =
200+ foldNType
201+ NTypeFolder
202+ { variableFolder = \_ _ -> S.empty,
203+ deBruijnFolder = \t n -> case t of
204+ DeBruijn m j | m == n -> S.singleton j
205+ _ -> S.empty,
206+ atomicFolder = \_ _ -> S.empty,
207+ compositeFolder = \f n -> f (n + 1)
208+ }
178209
179210showAtomicType :: AtomicType -> T.Builder
180211showAtomicType Integer = "Integer"
@@ -193,6 +224,7 @@ variableNames =
193224 greek <> fmap (\(n, g) -> g <> T.fromString (show n)) (zip [1 :: Int ..] greek)
194225
195226instance Pretty NType where
227+ pretty (NAtomic a) = viaShow a
196228 pretty (NTypeVariable t) = viaShow t
197229 pretty (NBruijn (DeBruijn i j)) = "⟦" <> pretty i <+> pretty j <> "⟧"
198230 pretty (x :-> y) = sep [pretty x, "->" <+> pretty y]
@@ -209,6 +241,5 @@ instance Pretty NType where
209241 ]
210242
211243instance Pretty Scheme where
212− pretty (NAtomic a) = viaShow a
213244 pretty ([] :=> t) = pretty t
214245 pretty (cs :=> t) = viaShow cs <+> "=>" <+> pretty t