@@ -1,18 +1,14 @@
11{-# OPTIONS_GHC -Wall #-}
22module Type.State
3− ( Solver
3+ ( Solver(..)
44 , run
55 , State(..)
6− , Pool(..)
6+ , Pools
77 , Env
88 , modifyEnv
99 , addError
10− , switchToPool
11− , getPool
1210 , getEnv
1311 , saveLocalEnv
14− , uniqueMark
15− , nextRankPool
1612 , register
1713 , introduce
1814 , flatten
@@ -21,11 +17,12 @@ module Type.State
2117 where
2218
2319
24−import Control.Monad (liftM, liftM2)
20+import Control.Monad (forM_, liftM, liftM2)
2521import Control.Monad.Trans (MonadIO, liftIO)
2622import qualified Data.Map as Map
2723import Data.Map ((!))
2824import Data.Text (Text)
25+import qualified Data.Vector.Mutable as MVector
2926
3027import qualified Reporting.Annotation as A
3128import qualified Reporting.Error.Type as Error
@@ -42,53 +39,32 @@ newtype Solver a =
4239 Solver { _solve :: State -> IO (a, State) }
4340
4441
45−
46−-- RUN SOLVER
47−
48−
49−run :: Solver () -> IO State
50−run (Solver solver) =
51− do (_, state) <- solver initialState
52− return state
53−
54−
55−initialState :: State
56−initialState =
42+data State =
5743 SS
58− { sEnv = Map.empty
59− , sSavedEnv = Map.empty
60− , sPool = Pool outermostRank []
61− , sMark = Type.nextMark noMark -- The mark must never be equal to noMark!
62− , sError = []
44+ { _env :: Env
45+ , _savedEnv :: Env
46+ , _rank :: Int
47+ , _pools :: Pools
48+ , _mark :: Mark
49+ , _errors :: [A.Located Error.Error]
6350 }
6451
6552
53+type Pools = MVector.IOVector [Variable]
6654
67−-- SOLVER STATE
6855
56+type Env = Map.Map Text (A.Located Variable)
6957
70−data State =
71− SS
72− { sEnv :: Env
73− , sSavedEnv :: Env
74− , sPool :: Pool
75− , sMark :: Mark
76− , sError :: [A.Located Error.Error]
77− }
7858
7959
80−{-| A pool holds a bunch of variables
81−The rank of each variable is less than or equal to the pool's "maxRank"
82−The young pool exists to make it possible to identify these vars in constant time.
83−-}
84−data Pool =
85− Pool
86− { _maxRank :: Int
87− , _inhabitants :: [Variable]
88− }
60+-- RUN SOLVER
8961
9062
91−type Env = Map.Map Text (A.Located Variable)
63+run :: Solver () -> IO State
64+run (Solver solver) =
65+ do pools <- MVector.replicate 8 []
66+ (_, state) <- solver (SS Map.empty Map.empty outermostRank pools (Type.nextMark noMark) [])
67+ return state
9268
9369
9470
@@ -99,96 +75,54 @@ type Env = Map.Map Text (A.Located Variable)
9975modifyEnv :: (Env -> Env) -> Solver ()
10076modifyEnv f =
10177 Solver $ \state ->
102− return ( (), state { sEnv = f (sEnv state) } )
103−
104−
105−{-# INLINE modifyPool #-}
106−modifyPool :: (Pool -> Pool) -> Solver ()
107−modifyPool f =
108− Solver $ \state ->
109− return ( (), state { sPool = f (sPool state) } )
78+ return ( (), state { _env = f (_env state) } )
11079
11180
11281{-# INLINE addError #-}
11382addError :: R.Region -> Error.Error -> Solver ()
11483addError region err =
11584 Solver $ \state ->
116− return ( (), state { sError = A.A region err : sError state } )
117−
118−
119−{-# INLINE switchToPool #-}
120−switchToPool :: Pool -> Solver ()
121−switchToPool pool =
122− modifyPool (\_ -> pool)
123−
124−
125−{-# INLINE getPool #-}
126−getPool :: Solver Pool
127−getPool =
128− Solver $ \state ->
129− return ( sPool state, state )
130−
131−
132−{-# INLINE getMaxRank #-}
133−getMaxRank :: Solver Int
134−getMaxRank =
135− Solver $ \state@(SS _ _ (Pool maxRank _) _ _) ->
136− return ( maxRank, state )
85+ return ( (), state { _errors = A.A region err : _errors state } )
13786
13887
13988{-# INLINE getEnv #-}
14089getEnv :: Solver Env
14190getEnv =
14291 Solver $ \state ->
143− return ( sEnv state, state )
92+ return ( _env state, state )
14493
14594
14695{-# INLINE saveLocalEnv #-}
14796saveLocalEnv :: Solver ()
14897saveLocalEnv =
14998 Solver $ \state ->
150− return ( (), state { sSavedEnv = sEnv state } )
151−
152−
153−{-# INLINE uniqueMark #-}
154−uniqueMark :: Solver Mark
155−uniqueMark =
156− Solver $ \(SS env savedEnv pool mark errors) ->
157− return ( mark, SS env savedEnv pool (Type.nextMark mark) errors )
158−
159−
160−{-# INLINE nextRankPool #-}
161−nextRankPool :: Solver Pool
162−nextRankPool =
163− Solver $ \state@(SS _ _ (Pool maxRank _) _ _) ->
164− return ( Pool (maxRank + 1) [], state )
99+ return ( (), state { _savedEnv = _env state } )
165100
166101
167102
168103-- REGISTER VARIABLES
169104
170105
171−{-# INLINE register #-}
172−register :: Variable -> Solver Variable
173−register variable =
174− {-# SCC elm_compiler_type_register #-}
175− Solver $ \state ->
176− let
177− (Pool maxRank inhabitants) =
178− sPool state
179− in
180− return ( variable, state { sPool = Pool maxRank (variable : inhabitants) } )
106+register :: Variable -> Solver ()
107+register var =
108+ Solver $ \state@(SS _ _ maxRank pools _ _) ->
109+ {-# SCC elm_compiler_type_register #-}
110+ do MVector.modify pools (var:) maxRank
111+ return ( (), state )
181112
182113
183−{-# INLINE introduce #-}
184114introduce :: [Variable] -> Solver ()
185115introduce variables =
186− {-# SCC elm_compiler_type_introduce #-}
187− Solver $ \(SS env savedEnv (Pool maxRank inhabitants) mark errors) ->
188− do let toMaxRank (Descriptor c _ m cp) = Descriptor c maxRank m cp
189− mapM_ (\var -> UF.modifyDescriptor var toMaxRank) variables
190− let newPool = Pool maxRank (variables ++ inhabitants)
191− return ( (), SS env savedEnv newPool mark errors )
116+ Solver $ \state@(SS _ _ maxRank pools _ _) ->
117+ {-# SCC elm_compiler_type_introduce #-}
118+ do
119+ forM_ variables $ \var ->
120+ UF.modifyDescriptor var $ \(Descriptor content _ mark cp) ->
121+ Descriptor content maxRank mark cp
122+
123+ MVector.modify pools (variables++) maxRank
124+
125+ return ( (), state )
192126
193127
194128
@@ -196,47 +130,50 @@ introduce variables =
196130
197131
198132flatten :: Type -> Solver Variable
199−flatten term =
200− {-# SCC elm_compiler_type_flatten #-}
201− do maxRank <- getMaxRank
202− flattenHelp maxRank Map.empty term
133+flatten tipe =
134+ Solver $ \state@(SS _ _ maxRank pools _ _) ->
135+ {-# SCC elm_compiler_type_flatten #-}
136+ do var <- flattenHelp maxRank pools Map.empty tipe
137+ return (var, state)
203138
204139
205−flattenHelp :: Int -> Map.Map Text Variable -> Type -> Solver Variable
206−flattenHelp maxRank aliasDict termN =
207− case termN of
140+flattenHelp :: Int -> Pools -> Map.Map Text Variable -> Type -> IO Variable
141+flattenHelp maxRank pools aliasDict tipe =
142+ case tipe of
208143 PlaceHolder name ->
209144 return (aliasDict ! name)
210145
211146 AliasN name args realType ->
212− do flatArgs <- mapM (traverse (flattenHelp maxRank aliasDict)) args
213− flatVar <- flattenHelp maxRank (Map.fromList flatArgs) realType
214− makeFlatType maxRank (Alias name flatArgs flatVar)
147+ do flatArgs <- mapM (traverse (flattenHelp maxRank pools aliasDict)) args
148+ flatVar <- flattenHelp maxRank pools (Map.fromList flatArgs) realType
149+ registerFlatType maxRank pools (Alias name flatArgs flatVar)
215150
216151 VarN v ->
217152 return v
218153
219154 AppN name args ->
220− do flatArgs <- traverse (flattenHelp maxRank aliasDict) args
221− makeFlatType maxRank (Structure (App1 name flatArgs))
155+ do flatArgs <- traverse (flattenHelp maxRank pools aliasDict) args
156+ registerFlatType maxRank pools (Structure (App1 name flatArgs))
222157
223158 FunN a b ->
224− do flatA <- flattenHelp maxRank aliasDict a
225− flatB <- flattenHelp maxRank aliasDict b
226− makeFlatType maxRank (Structure (Fun1 flatA flatB))
159+ do flatA <- flattenHelp maxRank pools aliasDict a
160+ flatB <- flattenHelp maxRank pools aliasDict b
161+ registerFlatType maxRank pools (Structure (Fun1 flatA flatB))
227162
228163 EmptyRecordN ->
229− makeFlatType maxRank (Structure EmptyRecord1)
164+ registerFlatType maxRank pools (Structure EmptyRecord1)
230165
231166 RecordN fields ext ->
232− do flatFields <- traverse (flattenHelp maxRank aliasDict) fields
233− flatExt <- flattenHelp maxRank aliasDict ext
234− makeFlatType maxRank (Structure (Record1 flatFields flatExt))
167+ do flatFields <- traverse (flattenHelp maxRank pools aliasDict) fields
168+ flatExt <- flattenHelp maxRank pools aliasDict ext
169+ registerFlatType maxRank pools (Structure (Record1 flatFields flatExt))
235170
236171
237−makeFlatType :: Int -> Content -> Solver Variable
238−makeFlatType maxRank content =
239− register =<< liftIO (UF.fresh (Descriptor content maxRank noMark Nothing))
172+registerFlatType :: Int -> Pools -> Content -> IO Variable
173+registerFlatType maxRank pools content =
174+ do var <- UF.fresh (Descriptor content maxRank noMark Nothing)
175+ MVector.modify pools (var:) maxRank
176+ return var
240177
241178
242179
@@ -245,16 +182,16 @@ makeFlatType maxRank content =
245182
246183copy :: Variable -> Solver Variable
247184copy var =
248− {-# SCC elm_compiler_type_copy #-}
249− do maxRank <- getMaxRank
250− copyVar <- copyHelp maxRank var
251− _ <- restore var
252− return copyVar
185+ Solver $ \state@(SS _ _ maxRank pools _ _) ->
186+ {-# SCC elm_compiler_type_copy #-}
187+ do copyVar <- copyHelp maxRank pools var
188+ _ <- restore var
189+ return ( copyVar, state )
253190
254191
255−copyHelp :: Int -> Variable -> Solver Variable
256−copyHelp maxRank variable =
257− do (Descriptor content rank _mark maybeCopy) <- liftIO $ UF.descriptor variable
192+copyHelp :: Int -> Pools -> Variable -> IO Variable
193+copyHelp maxRank pools variable =
194+ do (Descriptor content rank _mark maybeCopy) <- UF.descriptor variable
258195 case maybeCopy of
259196 Just copiedVariable ->
260197 return copiedVariable
@@ -265,15 +202,15 @@ copyHelp maxRank variable =
265202
266203 else
267204 do let mkCopyDesc cont = Descriptor cont maxRank noMark Nothing
268− newVar <- liftIO $ UF.fresh $ mkCopyDesc content
269− _ <- register newVar
205+ newVar <- UF.fresh $ mkCopyDesc content
206+ MVector.modify pools (newVar:) maxRank
270207
271208 -- Link the original variable to the new variable. This lets us
272209 -- avoid making multiple copies of the variable we are instantiating.
273210 --
274211 -- Need to do this before recursively copying the content of
275212 -- the variable to avoid looping on cyclic terms.
276− liftIO $ UF.setDescriptor variable $
213+ UF.setDescriptor variable $
277214 Descriptor content rank noMark (Just newVar)
278215
279216 -- Now we recursively copy the content of the variable.
@@ -281,19 +218,19 @@ copyHelp maxRank variable =
281218 -- will not repeat this work or crawl this variable again.
282219 case content of
283220 Structure term ->
284− do newTerm <- traverseFlatType (copyHelp maxRank) term
285− liftIO $ UF.setDescriptor newVar $ mkCopyDesc (Structure newTerm)
221+ do newTerm <- traverseFlatType (copyHelp maxRank pools) term
222+ UF.setDescriptor newVar $ mkCopyDesc (Structure newTerm)
286223
287224 Var Rigid maybeSuper maybeName ->
288− liftIO $ UF.setDescriptor newVar $ mkCopyDesc $ Var Flex maybeSuper maybeName
225+ UF.setDescriptor newVar $ mkCopyDesc $ Var Flex maybeSuper maybeName
289226
290227 Var Flex _ _ ->
291228 return ()
292229
293230 Alias name args realType ->
294− do newArgs <- mapM (traverse (copyHelp maxRank)) args
295− newRealType <- copyHelp maxRank realType
296− liftIO $ UF.setDescriptor newVar $ mkCopyDesc (Alias name newArgs newRealType)
231+ do newArgs <- mapM (traverse (copyHelp maxRank pools)) args
232+ newRealType <- copyHelp maxRank pools realType
233+ UF.setDescriptor newVar $ mkCopyDesc (Alias name newArgs newRealType)
297234
298235 Error _ ->
299236 return ()
@@ -305,21 +242,21 @@ copyHelp maxRank variable =
305242-- RESTORE
306243
307244
308−restore :: Variable -> Solver Variable
245+restore :: Variable -> IO Variable
309246restore variable =
310− do (Descriptor content _rank _mark maybeCopy) <- liftIO $ UF.descriptor variable
247+ do (Descriptor content _rank _mark maybeCopy) <- UF.descriptor variable
311248 case maybeCopy of
312249 Nothing ->
313250 return variable
314251
315252 Just _ ->
316253 do restoredContent <- restoreContent content
317− liftIO $ UF.setDescriptor variable $
254+ UF.setDescriptor variable $
318255 Descriptor restoredContent noRank noMark Nothing
319256 return variable
320257
321258
322−restoreContent :: Content -> Solver Content
259+restoreContent :: Content -> IO Content
323260restoreContent content =
324261 case content of
325262 Structure term ->
@@ -341,7 +278,7 @@ restoreContent content =
341278-- TRAVERSE FLAT TYPE
342279
343280
344−traverseFlatType :: (Variable -> Solver Variable) -> FlatType -> Solver FlatType
281+traverseFlatType :: (Variable -> IO Variable) -> FlatType -> IO FlatType
345282traverseFlatType f flatType =
346283 case flatType of
347284 App1 name args ->