@@ -28,39 +28,60 @@ import Data.Sequences
28import Data.Set (Set)
28import Data.Set (Set)
29import qualified Data.Set as S
29import qualified Data.Set as S
30import Data.Text (Text)
30import Data.Text (Text)
31+import qualified Data.Text.Lazy.Builder as T
31import Data.Traversable
32import Data.Traversable
32import Nix.Atoms
34import Nix.Atoms
33import Nix.Expr
35import Nix.Expr
35−getType :: NExprLoc -> (Either UnifyingError NType, [(SrcSpan, Errors)])
37+getType :: NExprLoc -> (NType, [(SrcSpan, Errors)], [UnifyingError])
36−getType exp =
38+getType r =
37− let (((t, srcs), cons), errs) =
39+ let ((((t, unifying), srcs), constraints), errs) =
39 . runReader (M.empty :: VariableMap)
41 . runReader (M.empty :: VariableMap)
40 . runSeqWriter @[(SrcSpan, Errors)]
42 . runSeqWriter @[(SrcSpan, Errors)]
41 . runSeqWriter @(Seq Constraint)
43 . runSeqWriter @(Seq Constraint)
42 . runSeqWriter @[(TypeVariable, SrcSpan)]
44 . runSeqWriter @[(TypeVariable, SrcSpan)]
45+ . runSeqWriter @[UnifyingError]
43 . runFresh
46 . runFresh
44− $ infer exp
47+ $ getType' r
45− s = run . runError @UnifyingError $ solve cons
48+ in (t, errs, unifying)
46− in ((`sub` t) <$> s, errs)
49+
52+ '[ Writer (SrcSpan, Errors),
54+ Writer (TypeVariable, SrcSpan),
55+ Writer UnifyingError,
63+ runSeqWriter @(Seq Constraint) $
65+ s <- solve (traceShowId constraints)
66+ return . close $ sub s (traceShowId t)
48newtype TypeVariable = TypeVariable Int
68newtype TypeVariable = TypeVariable Int
49 deriving newtype (Show, Eq, Ord)
69 deriving newtype (Show, Eq, Ord)
51data Constraint = !NType :~ !NType
71data Constraint = !NType :~ !NType
72+ deriving stock (Eq, Ord, Show)
53−newtype DeBrujin = DeBrujin {unDeBrujin :: Int}
74+data DeBrujin = DeBrujin !Int !Int
54− deriving newtype (Eq, Ord)
75+ deriving stock (Show, Eq, Ord)
55− deriving stock (Show)
58 = NTypeVariable !TypeVariable
78 = NTypeVariable !TypeVariable
59 | NBrujin !DeBrujin
79 | NBrujin !DeBrujin
60 | NAtomic !AtomicType
80 | NAtomic !AtomicType
62− | NAttrSet !(Map Text NType)
63 | !NType :-> !NType
81 | !NType :-> !NType
82+ | -- These two introduce a new De Brujin binding context
84+ | NAttrSet !(Map Text NType)
64 deriving stock (Eq, Ord, Show)
85 deriving stock (Eq, Ord, Show)
66data AtomicType
87data AtomicType
@@ -73,6 +94,43 @@ data AtomicType
74 deriving stock (Eq, Ord, Show)
95 deriving stock (Eq, Ord, Show)
97+isClosed :: NType -> Bool
98+isClosed (NTypeVariable _) = False
99+isClosed (NBrujin _) = True
100+isClosed (NAtomic _) = True
101+isClosed (x :-> y) = isClosed x && isClosed y
102+isClosed (List x) = isClosed x
103+isClosed (NAttrSet xs) = all isClosed . M.elems $ xs
105+close :: NType -> NType
108+ . evalState @(Map TypeVariable DeBrujin) M.empty
113+ -- State is the sequential number, Reader is the binding context number
114+ close' :: NType -> Eff '[State Int, Reader Int, State (Map TypeVariable DeBrujin)] NType
115+ close' x@(NAtomic _) = return x
116+ close' x@(NBrujin _) = return x
117+ close' (x :-> y) = (:->) <$> close' x <*> close' y
118+ close' (NTypeVariable tv) = NBrujin <$> newbrujin tv
119+ close' (List x) = bndCtx $ List <$> close' x
120+ close' (NAttrSet x) = bndCtx $ NAttrSet <$> traverse close' x
122+ bndCtx = local @Int (+ 1)
124+ get @(Map TypeVariable DeBrujin) <&> M.lookup t >>= \case
129+ let x = DeBrujin i j
130+ modify @(Map TypeVariable DeBrujin) (M.insert t x)
76class Free s where
134class Free s where
77 free :: s -> Set TypeVariable
135 free :: s -> Set TypeVariable
@@ -94,6 +152,7 @@ instance Monoid Substitution where
94sub :: Substitution -> NType -> NType
152sub :: Substitution -> NType -> NType
95sub s r = case r of
153sub s r = case r of
96 NAtomic _ -> r
154 NAtomic _ -> r
97 NTypeVariable x -> subTV x
156 NTypeVariable x -> subTV x
98 List x -> List $ sub s x
157 List x -> List $ sub s x
99 NAttrSet m -> NAttrSet $ sub s <$> m
158 NAttrSet m -> NAttrSet $ sub s <$> m
@@ -109,7 +168,7 @@ subCon s (x :~ y) = sub s x :~ sub s y
110 UnifyM Substitution
169 UnifyM Substitution
111v <<- (NTypeVariable x) | v == x = return mempty
170v <<- (NTypeVariable x) | v == x = return mempty
112−v <<- x | v `occursIn` x = throwError $ InfinityType x
171+v <<- x | v `occursIn` x = tell (InfinityType x) >> return mempty
113v <<- x = return $ Substitution $ M.singleton v x
172v <<- x = return $ Substitution $ M.singleton v x
115unify :: Constraint -> UnifyM Substitution
174unify :: Constraint -> UnifyM Substitution
@@ -127,7 +186,7 @@ unify (lhs :~ rhs) =
127 s <- unify (x1 :~ x2)
186 s <- unify (x1 :~ x2)
128 s' <- unify $ subCon s $ y1 :~ y2
187 s' <- unify $ subCon s $ y1 :~ y2
129 return $ s' <> s
188 return $ s' <> s
130− (x, y) -> throwError $ CanNotUnify x y
189+ (x, y) -> tell (CanNotUnify x y) >> return mempty
132solve :: Seq Constraint -> UnifyM Substitution
191solve :: Seq Constraint -> UnifyM Substitution
133solve Empty = return mempty
192solve Empty = return mempty
@@ -156,6 +215,7 @@ data Errors
156 = UndefinedVariable VarName
215 = UndefinedVariable VarName
157 | UnexpectedType {expected :: NType, got :: NType}
216 | UnexpectedType {expected :: NType, got :: NType}
158 | KeyNotPresent Text
217 | KeyNotPresent Text
218+ deriving stock (Eq, Ord, Show)
160data Fresh x where
220data Fresh x where
161 Fresh :: Fresh TypeVariable
221 Fresh :: Fresh TypeVariable
@@ -188,14 +248,15 @@ data UnifyingError
188 | CanNotUnify NType NType
248 | CanNotUnify NType NType
189 deriving stock (Eq, Show)
249 deriving stock (Eq, Show)
191−type UnifyM x = forall r. Members '[Error UnifyingError] r => Eff r x
251+type UnifyM x = forall r. Members '[Writer UnifyingError] r => Eff r x
193type InferEffs =
253type InferEffs =
194 '[ Fresh,
254 '[ Fresh,
195 Writer (TypeVariable, SrcSpan),
255 Writer (TypeVariable, SrcSpan),
196 Writer Constraint,
256 Writer Constraint,
197 Writer (SrcSpan, Errors),
257 Writer (SrcSpan, Errors),
198− Reader VariableMap
258+ Reader VariableMap,
259+ Writer UnifyingError
201type InferM x = forall r. Members InferEffs r => Eff r x
262type InferM x = forall r. Members InferEffs r => Eff r x