1{-# OPTIONS_GHC -Wall #-}
20import Control.Monad (forM_, liftM, liftM2, liftM3)
21import Control.Monad.Trans (MonadIO, liftIO)
22import qualified Data.Map.Strict as Map
23import Data.Map.Strict ((!))
24import qualified Data.Vector.Mutable as MVector
26import qualified Elm.Name as N
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 N.Name (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 N.Name Variable -> Type -> IO Variable
141flattenHelp maxRank pools aliasDict tipe =
144 return (aliasDict ! name)
146 AliasN home 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 home name flatArgs flatVar)
154 AppN home name args ->
155 do flatArgs <- traverse (flattenHelp maxRank pools aliasDict) args
156 registerFlatType maxRank pools (Structure (App1 home 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))
172 registerFlatType maxRank pools (Structure Unit1)
175 do flatA <- flattenHelp maxRank pools aliasDict a
176 flatB <- flattenHelp maxRank pools aliasDict b
177 flatCs <- traverse (flattenHelp maxRank pools aliasDict) cs
178 registerFlatType maxRank pools (Structure (Tuple1 flatA flatB flatCs))
181registerFlatType :: Int -> Pools -> Content -> IO Variable
182registerFlatType maxRank pools content =
183 do var <- UF.fresh (Descriptor content maxRank noMark Nothing)
184 MVector.modify pools (var:) maxRank
192copy :: Variable -> Solver Variable
194 Solver $ \state@(SS _ _ maxRank pools _ _) ->
195 {-# SCC elm_compiler_type_copy #-}
196 do copyVar <- copyHelp maxRank pools var
198 return ( copyVar, state )
201copyHelp :: Int -> Pools -> Variable -> IO Variable
202copyHelp maxRank pools variable =
203 do (Descriptor content rank _mark maybeCopy) <- UF.descriptor variable
205 Just copiedVariable ->
206 return copiedVariable
209 if rank /= noRank then
213 do let mkCopyDesc cont = Descriptor cont maxRank noMark Nothing
214 newVar <- UF.fresh $ mkCopyDesc content
215 MVector.modify pools (newVar:) maxRank
217 -- Link the original variable to the new variable. This lets us
218 -- avoid making multiple copies of the variable we are instantiating.
220 -- Need to do this before recursively copying the content of
221 -- the variable to avoid looping on cyclic terms.
222 UF.setDescriptor variable $
223 Descriptor content rank noMark (Just newVar)
225 -- Now we recursively copy the content of the variable.
226 -- We have already marked the variable as copied, so we
227 -- will not repeat this work or crawl this variable again.
230 do newTerm <- traverseFlatType (copyHelp maxRank pools) term
231 UF.setDescriptor newVar $ mkCopyDesc (Structure newTerm)
240 UF.setDescriptor newVar $ mkCopyDesc $ FlexVar (Just name)
242 RigidSuper super name ->
243 UF.setDescriptor newVar $ mkCopyDesc $ FlexSuper super (Just name)
245 Alias home name args realType ->
246 do newArgs <- mapM (traverse (copyHelp maxRank pools)) args
247 newRealType <- copyHelp maxRank pools realType
248 UF.setDescriptor newVar $ mkCopyDesc (Alias home name newArgs newRealType)
260restore :: Variable -> IO Variable
262 do (Descriptor content _rank _mark maybeCopy) <- UF.descriptor variable
268 do restoredContent <- restoreContent content
269 UF.setDescriptor variable $
270 Descriptor restoredContent noRank noMark Nothing
274restoreContent :: Content -> IO Content
275restoreContent content =
290 Structure <$> traverseFlatType restore term
292 Alias home name args var ->
294 <$> mapM (traverse restore) args
305traverseFlatType :: (Variable -> IO Variable) -> FlatType -> IO FlatType
306traverseFlatType f flatType =
308 App1 home name args ->
309 liftM (App1 home name) (traverse f args)
312 liftM2 Fun1 (f a) (f b)
317 Record1 fields ext ->
318 liftM2 Record1 (traverse f fields) (f ext)
324 liftM3 Tuple1 (f a) (f b) (traverse f cs)
331instance Functor Solver where
333 fmap f (Solver solver) =
335 fmap (\(a, s2) -> (f a, s2)) (solver s1)
338instance Applicative Solver where
341 Solver $ \s -> return (a, s)
344 Solver solverFunc <*> Solver solverValue =
346 do (f, s2) <- solverFunc s1
347 (x, s3) <- solverValue s2
351instance Monad Solver where
353 Solver solver >>= k =
355 do (a, s2) <- solver s1
356 (b, s3) <- _solve (k a) s2
361 Solver $ \_ -> fail msg
364instance MonadIO Solver where
365 {-# 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