@@ -35,65 +35,82 @@ import qualified Control.Category as C
36import qualified Data.Map as M
36import qualified Data.Map as M
38−data KindConstraint = KindConstraint Int Kind deriving Show
38+data KindConstraint = KindConstraint Int Kind
40+instance Show KindConstraint where
41+ show (KindConstraint n k) = show n ++ " = " ++ show k
40newtype KindSolution = KindSolution { runKindSolution :: Int -> Kind }
43newtype KindSolution = KindSolution { runKindSolution :: Int -> Kind }
42emptyKindSolution :: KindSolution
45emptyKindSolution :: KindSolution
43emptyKindSolution = KindSolution KUnknown
46emptyKindSolution = KindSolution KUnknown
45−kindsOf :: [String] -> [Type] -> Check [Kind]
48+kindsOf :: String -> [String] -> [Type] -> Check Kind
46−kindsOf args ts = do
49+kindsOf name args ts = do
51+ let nargs = [1..length args]
47− (cs, _, m) <- kindConstraintsAll 0 M.empty ts
52+ (cs, ns, _, m) <- kindConstraintsAll (length args + 1) (M.insert name tyCon $ M.fromList (zipWith (,) args nargs)) ts
53+ let extraConstraints = KindConstraint tyCon (foldr FunKind Star (map KUnknown nargs)) : map (flip KindConstraint Star) ns
48− solution <- solveKindConstraints cs emptyKindSolution
54+ solution <- solveKindConstraints (extraConstraints ++ cs) emptyKindSolution
49− return $ map (maybe Star starIfUnknown . fmap (runKindSolution solution) . flip M.lookup m) args
55+ return $ starIfUnknown $ runKindSolution solution 0
51starIfUnknown :: Kind -> Kind
57starIfUnknown :: Kind -> Kind
52starIfUnknown (KUnknown _) = Star
58starIfUnknown (KUnknown _) = Star
53starIfUnknown (FunKind k1 k2) = FunKind (starIfUnknown k1) (starIfUnknown k2)
59starIfUnknown (FunKind k1 k2) = FunKind (starIfUnknown k1) (starIfUnknown k2)
54starIfUnknown k = k
60starIfUnknown k = k
56−kindConstraintsAll :: Int -> M.Map String Int -> [Type] -> Check ([KindConstraint], [Int], M.Map String Int)
62+kindConstraintsAll :: Int -> M.Map String Int -> [Type] -> Check ([KindConstraint], [Int], Int, M.Map String Int)
57−kindConstraintsAll _ m [] = return ([], [], m)
63+kindConstraintsAll n m [] = return ([], [], n, m)
58kindConstraintsAll n m (t:ts) = do
64kindConstraintsAll n m (t:ts) = do
59− (cs, n', m') <- kindConstraints n m t
65+ (cs, n1, max1, m') <- kindConstraints n m t
60− (cs', ns, m'') <- kindConstraintsAll (n' + 1) m' ts
66+ (cs', ns, max2, m'') <- kindConstraintsAll (max1 + 1) m' ts
61− return ((KindConstraint n' Star) : cs ++ cs', n':ns, m'')
67+ return ((KindConstraint n1 Star) : cs ++ cs', n1:ns, max2, m'')
63−kindConstraints :: Int -> M.Map String Int -> Type -> Check ([KindConstraint], Int, M.Map String Int)
69+kindConstraints :: Int -> M.Map String Int -> Type -> Check ([KindConstraint], Int, Int, M.Map String Int)
64kindConstraints n m (Array t) = do
70kindConstraints n m (Array t) = do
65− (cs, n', m') <- kindConstraints n m t
72+ (cs, n1, max1, m') <- kindConstraints (n + 1) m t
66− return ((KindConstraint n' Star) : (KindConstraint (n' + 1) Star) : cs, n' + 1, m')
73+ return ((KindConstraint n1 Star) : (KindConstraint me Star) : cs, me, max1, m')
67kindConstraints n m (Object row) = do
74kindConstraints n m (Object row) = do
68 let me = n
75 let me = n
69− (cs, row, m') <- kindConstraintsForRow (n + 2) m row
76+ (cs, row, max1, m') <- kindConstraintsForRow (n + 1) m row
70− return ((KindConstraint me Star) : (KindConstraint row Row) : cs, me, m')
77+ return ((KindConstraint me Star) : (KindConstraint row Row) : cs, me, max1, m')
71kindConstraints n m (Function args ret) = do
78kindConstraints n m (Function args ret) = do
72− (cs, ns, m') <- kindConstraintsAll n m args
80+ (cs, ns, max1, m') <- kindConstraintsAll (n + 1) m args
73− let next = maximum ns + 1
74− (cs', retN, m'') <- kindConstraints next m' ret
81+ (cs', retN, max2, m'') <- kindConstraints (max1 + 1) m' ret
76− return ((KindConstraint retN Star) : (KindConstraint me Star) : (map (flip KindConstraint Star) ns) ++ cs, me, m'')
82+ return ((KindConstraint retN Star) : (KindConstraint me Star) : (map (flip KindConstraint Star) ns) ++ cs, me, max2, m'')
77kindConstraints n m (TypeVar v) =
83kindConstraints n m (TypeVar v) =
79− n' = maybe n id (M.lookup v m)
84+ let n' = maybe n id (M.lookup v m)
80− in return ([], n', M.insert v n' m)
85+ in return ([], n', n, M.insert v n' m)
81kindConstraints n m (TypeConstructor v) = do
86kindConstraints n m (TypeConstructor v) = do
82 env <- get
87 env <- get
88+ kind <- case M.lookup v m of
89+ Nothing -> case M.lookup v (types env) of
83− kind <- maybe (throwError "Unknown type constructor") return (M.lookup v (types env))
90+ Nothing -> throwError $ "Unknown type constructor '" ++ v ++ "'"
92+ Just u -> return (KUnknown u)
84− return ([KindConstraint n kind], n, m)
93+ return ([KindConstraint n kind], n, n, m)
85kindConstraints n m (TypeApp t1 t2) = do
94kindConstraints n m (TypeApp t1 t2) = do
86− (cs1, n1, m1) <- kindConstraints n m t1
96+ (cs1, n1, max1, m1) <- kindConstraints (n + 1) m t1
87− (cs2, n2, m2) <- kindConstraints (n1 + 1) m1 t2
97+ (cs2, n2, max2, m2) <- kindConstraints (max1 + 1) m1 t2
88− return ((KindConstraint n1 (FunKind (KUnknown n2) (KUnknown (n2 + 1)))) : cs1 ++ cs2, n2 + 1, m2)
98+ return ((KindConstraint n1 (FunKind (KUnknown n2) (KUnknown me))) : cs1 ++ cs2, me, max2, m2)
89−kindConstraints n m _ = return ([KindConstraint n Star], n, m)
99+kindConstraints n m _ = return ([KindConstraint n Star], n, n, m)
91−kindConstraintsForRow :: Int -> M.Map String Int -> Row -> Check ([KindConstraint], Int, M.Map String Int)
101+kindConstraintsForRow :: Int -> M.Map String Int -> Row -> Check ([KindConstraint], Int, Int, M.Map String Int)
92−kindConstraintsForRow = undefined
102+kindConstraintsForRow n m (RowVar v) =
103+ let n' = maybe n id (M.lookup v m)
104+ in return ([KindConstraint n' Row], n', n, M.insert v n' m)
105+kindConstraintsForRow n m REmpty = return ([KindConstraint n Row], n, n, m)
106+kindConstraintsForRow n m (RCons _ ty row) = do
107+ (cs1, n1, max1, m1) <- kindConstraints (n + 1) m ty
108+ (cs2, n2, max2, m2) <- kindConstraintsForRow (max1 + 1) m1 row
109+ return ((KindConstraint n Row) : (KindConstraint n1 Star) : (KindConstraint n2 Row) : cs1 ++ cs2, n, max2, m2)
94solveKindConstraints :: [KindConstraint] -> KindSolution -> Check KindSolution
111solveKindConstraints :: [KindConstraint] -> KindSolution -> Check KindSolution
95solveKindConstraints [] s = return s
112solveKindConstraints [] s = return s
96−solveKindConstraints (KindConstraint n k:cs) s = do
113+solveKindConstraints all@(KindConstraint n k:cs) s = do
97 guardWith "Occurs check failed" $ not $ kindOccursCheck n k
114 guardWith "Occurs check failed" $ not $ kindOccursCheck n k
98 let s' = KindSolution $ replaceUnknownKind n k . runKindSolution s
115 let s' = KindSolution $ replaceUnknownKind n k . runKindSolution s
99 cs' <- fmap concat $ mapM (substituteKindConstraint n k) cs
116 cs' <- fmap concat $ mapM (substituteKindConstraint n k) cs
@@ -112,6 +129,7 @@ replaceUnknownKind n k = f
112 f other = other
129 f other = other
114unifyKinds :: Kind -> Kind -> Check [KindConstraint]
131unifyKinds :: Kind -> Kind -> Check [KindConstraint]
132+unifyKinds (KUnknown u1) (KUnknown u2) | u1 == u2 = return []
115unifyKinds (KUnknown u) k = do
133unifyKinds (KUnknown u) k = do
116 guardWith "Occurs check failed" $ not $ kindOccursCheck u k
134 guardWith "Occurs check failed" $ not $ kindOccursCheck u k
117 return [KindConstraint u k]
135 return [KindConstraint u k]
@@ -119,6 +137,7 @@ unifyKinds k (KUnknown u) = do
119 guardWith "Occurs check failed" $ not $ kindOccursCheck u k
137 guardWith "Occurs check failed" $ not $ kindOccursCheck u k
120 return [KindConstraint u k]
138 return [KindConstraint u k]
121unifyKinds Star Star = return []
139unifyKinds Star Star = return []
140+unifyKinds Row Row = return []
122unifyKinds (FunKind k1 k2) (FunKind k3 k4) = do
141unifyKinds (FunKind k1 k2) (FunKind k3 k4) = do
123 cs1 <- unifyKinds k1 k3
142 cs1 <- unifyKinds k1 k3
124 cs2 <- unifyKinds k2 k4
143 cs2 <- unifyKinds k2 k4