@@ -2,7 +2,7 @@
2module Type.State
2module Type.State
5− , SolverState(..)
5+ , State(..)
8 , modifyEnv
8 , modifyEnv
@@ -21,7 +21,9 @@ module Type.State
24−import qualified Control.Monad.State as State
24+
25+import Control.Monad (liftM2)
26+import Control.Monad.Trans (MonadIO, liftIO)
25import qualified Data.Map as Map
27import qualified Data.Map as Map
26import Data.Map ((!))
28import Data.Map ((!))
27import Data.Text (Text)
29import Data.Text (Text)
@@ -33,29 +35,40 @@ import qualified Reporting.Region as R
33import Type.Type
35import Type.Type
39−type Solver = State.StateT SolverState IO
42+newtype Solver a =
43+ Solver { _solve :: State -> IO (a, State) }
42−run :: Solver () -> IO SolverState
50+run :: Solver () -> IO State
43−run solver =
51+run (Solver solver) =
44− State.execStateT solver $
52+ do (_, state) <- solver initialState
46− { sEnv = Map.empty
59+ { sEnv = Map.empty
47− , sSavedEnv = Map.empty
60+ , sSavedEnv = Map.empty
48− , sPool = Pool outermostRank []
61+ , sPool = Pool outermostRank []
49− , sMark = noMark + 1 -- The mark must never be equal to noMark!
62+ , sMark = noMark + 1 -- The mark must never be equal to noMark!
50− , sError = []
63+ , sError = []
55-- SOLVER STATE
68-- SOLVER STATE
58−data SolverState =
71+data State =
60 { sEnv :: Env
73 { sEnv :: Env
61 , sSavedEnv :: Env
74 , sSavedEnv :: Env
@@ -71,8 +84,8 @@ The young pool exists to make it possible to identify these vars in constant tim
72data Pool =
85data Pool =
74− { maxRank :: Int
87+ { _maxRank :: Int
75− , inhabitants :: [Variable]
88+ , _inhabitants :: [Variable]
@@ -83,67 +96,105 @@ type Env = Map.Map Text (A.Located Variable)
99+{-# INLINE modifyEnv #-}
86modifyEnv :: (Env -> Env) -> Solver ()
100modifyEnv :: (Env -> Env) -> Solver ()
87modifyEnv f =
101modifyEnv f =
88− State.modify $ \state -> state { sEnv = f (sEnv state) }
103+ return ( (), state { sEnv = f (sEnv state) } )
106+{-# INLINE modifyPool #-}
91modifyPool :: (Pool -> Pool) -> Solver ()
107modifyPool :: (Pool -> Pool) -> Solver ()
92modifyPool f =
108modifyPool f =
93− State.modify $ \state -> state { sPool = f (sPool state) }
110+ return ( (), state { sPool = f (sPool state) } )
113+{-# INLINE addError #-}
96addError :: R.Region -> Error.Error -> Solver ()
114addError :: R.Region -> Error.Error -> Solver ()
97addError region err =
115addError region err =
98− State.modify $ \state -> state { sError = A.A region err : sError state }
117+ return ( (), state { sError = A.A region err : sError state } )
120+{-# INLINE switchToPool #-}
101switchToPool :: Pool -> Solver ()
121switchToPool :: Pool -> Solver ()
102switchToPool pool =
122switchToPool pool =
103− modifyPool (\_ -> pool)
123+ modifyPool (\_ -> pool)
126+{-# INLINE getPool #-}
106getPool :: Solver Pool
127getPool :: Solver Pool
108− State.gets sPool
129+ Solver $ \state ->
130+ return ( sPool state, state )
133+{-# INLINE getEnv #-}
111getEnv :: Solver Env
134getEnv :: Solver Env
113− State.gets sEnv
136+ Solver $ \state ->
137+ return ( sEnv state, state )
140+{-# INLINE saveLocalEnv #-}
116saveLocalEnv :: Solver ()
141saveLocalEnv :: Solver ()
117saveLocalEnv =
142saveLocalEnv =
118− do currentEnv <- getEnv
143+ Solver $ \state ->
119− State.modify $ \state -> state { sSavedEnv = currentEnv }
144+ return ( (), state { sSavedEnv = sEnv state } )
147+{-# INLINE uniqueMark #-}
122uniqueMark :: Solver Int
148uniqueMark :: Solver Int
123uniqueMark =
149uniqueMark =
124− do state <- State.get
150+ Solver $ \state ->
125− let mark = sMark state
151+ let
126− State.put $ state { sMark = mark + 1 }
155+ return ( mark, state { sMark = mark + 1 } )
158+{-# INLINE nextRankPool #-}
130nextRankPool :: Solver Pool
159nextRankPool :: Solver Pool
131nextRankPool =
160nextRankPool =
132− do pool <- getPool
161+ Solver $ \state ->
133− return $ Pool { maxRank = maxRank pool + 1, inhabitants = [] }
162+ let
166+ return ( Pool (maxRank + 1) [], state )
170+-- REGISTER VARIABLES
173+{-# INLINE register #-}
136register :: Variable -> Solver Variable
174register :: Variable -> Solver Variable
137register variable =
175register variable =
138− do modifyPool $ \pool -> pool { inhabitants = variable : inhabitants pool }
176+ Solver $ \state ->
139− return variable
177+ let
178+ (Pool maxRank inhabitants) =
181+ return ( variable, state { sPool = Pool maxRank (variable : inhabitants) } )
184+{-# INLINE introduce #-}
142introduce :: Variable -> Solver Variable
185introduce :: Variable -> Solver Variable
143introduce variable =
186introduce variable =
144− do pool <- getPool
187+ Solver $ \state ->
189+ (Pool maxRank inhabitants) =
145− State.liftIO $ UF.modifyDescriptor variable (\desc -> desc { _rank = maxRank pool })
192+ do UF.modifyDescriptor variable (\desc -> desc { _rank = maxRank })
146− register variable
193+ return ( variable, state { sPool = Pool maxRank (variable : inhabitants) } )
149flatten :: Type -> Solver Variable
200flatten :: Type -> Solver Variable
@@ -162,9 +213,9 @@ flattenHelp aliasDict termN =
162 flatVar <- flattenHelp (Map.fromList flatArgs) realType
213 flatVar <- flattenHelp (Map.fromList flatArgs) realType
163 pool <- getPool
214 pool <- getPool
164 variable <-
215 variable <-
165− State.liftIO . UF.fresh $ Descriptor
216+ liftIO . UF.fresh $ Descriptor
166 { _content = Alias name flatArgs flatVar
217 { _content = Alias name flatArgs flatVar
167− , _rank = maxRank pool
218+ , _rank = _maxRank pool
168 , _mark = noMark
219 , _mark = noMark
169 , _copy = Nothing
220 , _copy = Nothing
@@ -177,15 +228,19 @@ flattenHelp aliasDict termN =
177 do variableTerm <- traverseTerm (flattenHelp aliasDict) term1
228 do variableTerm <- traverseTerm (flattenHelp aliasDict) term1
178 pool <- getPool
229 pool <- getPool
179 variable <-
230 variable <-
180− State.liftIO . UF.fresh $ Descriptor
231+ liftIO . UF.fresh $ Descriptor
181 { _content = Structure variableTerm
232 { _content = Structure variableTerm
182− , _rank = maxRank pool
233+ , _rank = _maxRank pool
183 , _mark = noMark
234 , _mark = noMark
184 , _copy = Nothing
235 , _copy = Nothing
186 register variable
237 register variable
189makeInstance :: Variable -> Solver Variable
244makeInstance :: Variable -> Solver Variable
190makeInstance var =
245makeInstance var =
191 do alreadyCopiedMark <- uniqueMark
246 do alreadyCopiedMark <- uniqueMark
@@ -194,9 +249,13 @@ makeInstance var =
194 return freshVar
249 return freshVar
197makeCopy :: Int -> Variable -> Solver Variable
256makeCopy :: Int -> Variable -> Solver Variable
198makeCopy alreadyCopiedMark variable =
257makeCopy alreadyCopiedMark variable =
199− do desc <- State.liftIO $ UF.descriptor variable
258+ do desc <- liftIO $ UF.descriptor variable
200 makeCopyHelp desc alreadyCopiedMark variable
259 makeCopyHelp desc alreadyCopiedMark variable
@@ -220,9 +279,9 @@ makeCopyHelp (Descriptor content rank mark copy) alreadyCopiedMark variable =
221 do pool <- getPool
280 do pool <- getPool
222 newVar <-
281 newVar <-
223− State.liftIO $ UF.fresh $ Descriptor
282+ liftIO $ UF.fresh $ Descriptor
224 { _content = content -- place holder!
283 { _content = content -- place holder!
225− , _rank = maxRank pool
284+ , _rank = _maxRank pool
226 , _mark = noMark
285 , _mark = noMark
227 , _copy = Nothing
286 , _copy = Nothing
@@ -233,12 +292,12 @@ makeCopyHelp (Descriptor content rank mark copy) alreadyCopiedMark variable =
234 -- Need to do this before recursively copying the content of
293 -- Need to do this before recursively copying the content of
235 -- the variable to avoid looping on cyclic terms.
294 -- the variable to avoid looping on cyclic terms.
236− State.liftIO $ UF.modifyDescriptor variable $ \desc ->
295+ liftIO $ UF.modifyDescriptor variable $ \desc ->
237 desc { _mark = alreadyCopiedMark, _copy = Just newVar }
296 desc { _mark = alreadyCopiedMark, _copy = Just newVar }
240 let setContent newContent =
299 let setContent newContent =
241− State.liftIO $ UF.modifyDescriptor newVar $ \desc ->
300+ liftIO $ UF.modifyDescriptor newVar $ \desc ->
242 desc { _content = newContent }
301 desc { _content = newContent }
244 -- Now we recursively copy the content of the variable.
303 -- Now we recursively copy the content of the variable.
@@ -291,9 +350,12 @@ needsCopy content =
294restore :: Int -> Variable -> Solver Variable
356restore :: Int -> Variable -> Solver Variable
295restore alreadyCopiedMark variable =
357restore alreadyCopiedMark variable =
296− do desc <- State.liftIO $ UF.descriptor variable
358+ do desc <- liftIO $ UF.descriptor variable
297 if _mark desc /= alreadyCopiedMark
359 if _mark desc /= alreadyCopiedMark
299 return variable
361 return variable
@@ -301,7 +363,7 @@ restore alreadyCopiedMark variable =
302 do restoredContent <-
364 do restoredContent <-
303 restoreContent alreadyCopiedMark (_content desc)
365 restoreContent alreadyCopiedMark (_content desc)
304− State.liftIO $ UF.setDescriptor variable $ Descriptor
366+ liftIO $ UF.setDescriptor variable $ Descriptor
305 { _content = restoredContent
367 { _content = restoredContent
306 , _rank = noRank
368 , _rank = noRank
307 , _mark = noMark
369 , _mark = noMark
@@ -339,17 +401,60 @@ restoreContent alreadyCopiedMark content =
339-- TERM TRAVERSAL
401-- TERM TRAVERSAL
342−traverseTerm :: (Monad f, Applicative f) => (a -> f b) -> Term1 a -> f (Term1 b)
404+traverseTerm :: (a -> Solver b) -> Term1 a -> Solver (Term1 b)
343traverseTerm f term =
405traverseTerm f term =
344 case term of
406 case term of
345 App1 a b ->
407 App1 a b ->
346− App1 <$> f a <*> f b
408+ liftM2 App1 (f a) (f b)
348 Fun1 a b ->
410 Fun1 a b ->
349− Fun1 <$> f a <*> f b
411+ liftM2 Fun1 (f a) (f b)
351 EmptyRecord1 ->
413 EmptyRecord1 ->
352− return EmptyRecord1
414+ pure EmptyRecord1
354 Record1 fields ext ->
416 Record1 fields ext ->
355− Record1 <$> traverse f fields <*> f ext
417+ liftM2 Record1 (traverse f fields) (f ext)
424+instance Functor Solver where
426+ fmap f (Solver solver) = Solver $ \s1 ->
427+ fmap (\(a, s2) -> (f a, s2)) (solver s1)
430+instance Applicative Solver where
432+ pure a = Solver $ \s -> return (a, s)
434+ {-# INLINE (<*>) #-}
435+ Solver solverFunc <*> Solver solverValue =
437+ do (f, s2) <- solverFunc s1
438+ (x, s3) <- solverValue s2
442+instance Monad Solver where
443+ {-# INLINE (>>=) #-}
444+ Solver solver >>= k =
446+ do (a, s2) <- solver s1
447+ (b, s3) <- _solve (k a) s2
452+ Solver $ \_ -> fail msg
455+instance MonadIO Solver where
456+ {-# INLINE liftIO #-}