1{-# OPTIONS_GHC -Wall #-}
20import Control.Monad (forM_, liftM, liftM2)
21import Control.Monad.Trans (MonadIO, liftIO)
22import qualified Data.Map as Map
24import Data.Text (Text)
25import qualified Data.Vector.Mutable as MVector
27import qualified Reporting.Annotation as A
28import qualified Reporting.Error.Type as Error
29import qualified Reporting.Region as R
30import Type.Type as Type
31import qualified Type.UnionFind as UF
39 Solver { _solve :: State -> IO (a, State) }
49 , _errors :: [A.Located Error.Error]
53type Pools = MVector.IOVector [Variable]
56type Env = Map.Map Text (A.Located Variable)
63run :: Solver () -> IO State
65 do pools <- MVector.replicate 8 []
66 (_, state) <- solver (SS Map.empty Map.empty outermostRank pools (Type.nextMark noMark) [])
74{-# INLINE modifyEnv #-}
75modifyEnv :: (Env -> Env) -> Solver ()
78 return ( (), state { _env = f (_env state) } )
81{-# INLINE addError #-}
82addError :: R.Region -> Error.Error -> Solver ()
85 return ( (), state { _errors = A.A region err : _errors state } )
92 return ( _env state, state )
95{-# INLINE saveLocalEnv #-}
96saveLocalEnv :: Solver ()
99 return ( (), state { _savedEnv = _env state } )
106register :: Variable -> Solver ()
108 Solver $ \state@(SS _ _ maxRank pools _ _) ->
109 {-# SCC elm_compiler_type_register #-}
110 do MVector.modify pools (var:) maxRank
114introduce :: [Variable] -> Solver ()
116 Solver $ \state@(SS _ _ maxRank pools _ _) ->
117 {-# SCC elm_compiler_type_introduce #-}
119 forM_ variables $ \var ->
120 UF.modifyDescriptor var $ \(Descriptor content _ mark cp) ->
121 Descriptor content maxRank mark cp
123 MVector.modify pools (variables++) maxRank
132flatten :: Type -> Solver Variable
134 Solver $ \state@(SS _ _ maxRank pools _ _) ->
135 {-# SCC elm_compiler_type_flatten #-}
136 do var <- flattenHelp maxRank pools Map.empty tipe
140flattenHelp :: Int -> Pools -> Map.Map Text Variable -> Type -> IO Variable
141flattenHelp maxRank pools aliasDict tipe =
144 return (aliasDict ! name)
146 AliasN name args realType ->
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)
155 do flatArgs <- traverse (flattenHelp maxRank pools aliasDict) args
156 registerFlatType maxRank pools (Structure (App1 name flatArgs))
159 do flatA <- flattenHelp maxRank pools aliasDict a
160 flatB <- flattenHelp maxRank pools aliasDict b
161 registerFlatType maxRank pools (Structure (Fun1 flatA flatB))
164 registerFlatType maxRank pools (Structure EmptyRecord1)
166 RecordN fields ext ->
167 do flatFields <- traverse (flattenHelp maxRank pools aliasDict) fields
168 flatExt <- flattenHelp maxRank pools aliasDict ext
169 registerFlatType maxRank pools (Structure (Record1 flatFields flatExt))
172registerFlatType :: Int -> Pools -> Content -> IO Variable
173registerFlatType maxRank pools content =
174 do var <- UF.fresh (Descriptor content maxRank noMark Nothing)
175 MVector.modify pools (var:) maxRank
183copy :: Variable -> Solver Variable
185 Solver $ \state@(SS _ _ maxRank pools _ _) ->
186 {-# SCC elm_compiler_type_copy #-}
187 do copyVar <- copyHelp maxRank pools var
189 return ( copyVar, state )
192copyHelp :: Int -> Pools -> Variable -> IO Variable
193copyHelp maxRank pools variable =
194 do (Descriptor content rank _mark maybeCopy) <- UF.descriptor variable
196 Just copiedVariable ->
197 return copiedVariable
200 if rank /= noRank then
204 do let mkCopyDesc cont = Descriptor cont maxRank noMark Nothing
205 newVar <- UF.fresh $ mkCopyDesc content
206 MVector.modify pools (newVar:) maxRank
208 -- Link the original variable to the new variable. This lets us
209 -- avoid making multiple copies of the variable we are instantiating.
211 -- Need to do this before recursively copying the content of
212 -- the variable to avoid looping on cyclic terms.
213 UF.setDescriptor variable $
214 Descriptor content rank noMark (Just newVar)
216 -- Now we recursively copy the content of the variable.
217 -- We have already marked the variable as copied, so we
218 -- will not repeat this work or crawl this variable again.
221 do newTerm <- traverseFlatType (copyHelp maxRank pools) term
222 UF.setDescriptor newVar $ mkCopyDesc (Structure newTerm)
231 UF.setDescriptor newVar $ mkCopyDesc $ FlexVar (Just name)
233 RigidSuper super name ->
234 UF.setDescriptor newVar $ mkCopyDesc $ FlexSuper super (Just name)
236 Alias name args realType ->
237 do newArgs <- mapM (traverse (copyHelp maxRank pools)) args
238 newRealType <- copyHelp maxRank pools realType
239 UF.setDescriptor newVar $ mkCopyDesc (Alias name newArgs newRealType)
251restore :: Variable -> IO Variable
253 do (Descriptor content _rank _mark maybeCopy) <- UF.descriptor variable
259 do restoredContent <- restoreContent content
260 UF.setDescriptor variable $
261 Descriptor restoredContent noRank noMark Nothing
265restoreContent :: Content -> IO Content
266restoreContent content =
281 Structure <$> traverseFlatType restore term
283 Alias name args var ->
285 <$> mapM (traverse restore) args
296traverseFlatType :: (Variable -> IO Variable) -> FlatType -> IO FlatType
297traverseFlatType f flatType =
300 liftM (App1 name) (traverse f args)
303 liftM2 Fun1 (f a) (f b)
308 Record1 fields ext ->
309 liftM2 Record1 (traverse f fields) (f ext)
316instance Functor Solver where
318 fmap f (Solver solver) =
320 fmap (\(a, s2) -> (f a, s2)) (solver s1)
323instance Applicative Solver where
326 Solver $ \s -> return (a, s)
329 Solver solverFunc <*> Solver solverValue =
331 do (f, s2) <- solverFunc s1
332 (x, s3) <- solverValue s2
336instance Monad Solver where
338 Solver solver >>= k =
340 do (a, s2) <- solver s1
341 (b, s3) <- _solve (k a) s2
346 Solver $ \_ -> fail msg
349instance MonadIO Solver where
350 {-# INLINE liftIO #-}
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list