@@ -19,6 +19,8 @@ module Type.Type
19 , nameToFlex
19 , nameToFlex
20 , nameToRigid
20 , nameToRigid
21 , toSrcType
21 , toSrcType
@@ -26,13 +28,15 @@ import Control.Monad.State.Strict (StateT, liftIO)
26import qualified Control.Monad.State.Strict as State
28import qualified Control.Monad.State.Strict as State
27import qualified Data.Char as Char
29import qualified Data.Char as Char
28import qualified Data.Map.Strict as Map
30import qualified Data.Map.Strict as Map
31+import Data.Map.Strict ((!))
29import Data.Monoid ((<>))
32import Data.Monoid ((<>))
30import qualified Data.Text as Text
33import qualified Data.Text as Text
31import Data.Text (Text)
34import Data.Text (Text)
32import Data.Word (Word32)
35import Data.Word (Word32)
37+import qualified AST.Module.Name as ModuleName
34import qualified AST.Type as T
38import qualified AST.Type as T
35−import qualified AST.Variable as Var
39+import qualified Elm.Name as N
36import qualified Type.UnionFind as UF
40import qualified Type.UnionFind as UF
@@ -45,20 +49,24 @@ type Variable =
47data FlatType
51data FlatType
48− = App1 Var.Canonical [Variable]
52+ = App1 ModuleName.Canonical N.Name [Variable]
49 | Fun1 Variable Variable
53 | Fun1 Variable Variable
50 | EmptyRecord1
54 | EmptyRecord1
51 | Record1 (Map.Map Text Variable) Variable
55 | Record1 (Map.Map Text Variable) Variable
57+ | Tuple1 Variable Variable [Variable]
55 = PlaceHolder Text
61 = PlaceHolder Text
56− | AliasN Var.Canonical [(Text, Type)] Type
62+ | AliasN ModuleName.Canonical N.Name [(Text, Type)] Type
57 | VarN Variable
63 | VarN Variable
58− | AppN Var.Canonical [Type]
64+ | AppN ModuleName.Canonical N.Name [Type]
59 | FunN Type Type
65 | FunN Type Type
60 | EmptyRecordN
66 | EmptyRecordN
61 | RecordN (Map.Map Text Type) Type
67 | RecordN (Map.Map Text Type) Type
69+ | TupleN Type Type [Type]
@@ -80,7 +88,7 @@ data Content
80 | RigidVar Text
88 | RigidVar Text
81 | RigidSuper T.Super Text
89 | RigidSuper T.Super Text
82 | Structure FlatType
90 | Structure FlatType
83− | Alias Var.Canonical [(Text,Variable)] Variable
91+ | Alias ModuleName.Canonical N.Name [(Text,Variable)] Variable
84 | Error Text
92 | Error Text
@@ -148,25 +156,25 @@ infixr 9 ==>
148{-# NOINLINE float #-}
156{-# NOINLINE float #-}
149float :: Type
157float :: Type
151− AppN Var.float []
159+ AppN ModuleName.basics "Float" []
154{-# NOINLINE char #-}
162{-# NOINLINE char #-}
155char :: Type
163char :: Type
157− AppN Var.char []
165+ AppN ModuleName.basics "Char" []
160{-# NOINLINE string #-}
168{-# NOINLINE string #-}
161string :: Type
169string :: Type
163− AppN Var.string []
171+ AppN ModuleName.basics "String" []
166{-# NOINLINE bool #-}
174{-# NOINLINE bool #-}
167bool :: Type
175bool :: Type
169− AppN Var.bool []
177+ AppN ModuleName.basics "Bool" []
@@ -214,19 +222,19 @@ unnamedFlexSuper super =
214-- MAKE NAMED VARIABLES
222-- MAKE NAMED VARIABLES
217−nameToFlex :: Text -> IO Variable
225+nameToFlex :: N.Name -> IO Variable
218nameToFlex name =
226nameToFlex name =
219 UF.fresh $ makeDescriptor $
227 UF.fresh $ makeDescriptor $
220 maybe FlexVar FlexSuper (toSuper name) (Just name)
228 maybe FlexVar FlexSuper (toSuper name) (Just name)
223−nameToRigid :: Text -> IO Variable
231+nameToRigid :: N.Name -> IO Variable
224nameToRigid name =
232nameToRigid name =
225 UF.fresh $ makeDescriptor $
233 UF.fresh $ makeDescriptor $
226 maybe RigidVar RigidSuper (toSuper name) name
234 maybe RigidVar RigidSuper (toSuper name) name
229−toSuper :: Text -> Maybe T.Super
237+toSuper :: N.Name -> Maybe T.Super
230toSuper name =
238toSuper name =
231 if Text.isPrefixOf "number" name then
239 if Text.isPrefixOf "number" name then
232 Just T.Number
240 Just T.Number
@@ -245,7 +253,105 @@ toSuper name =
259+-- TODO should the freeFlexVars be ranked a certain way?
260+-- How does this interact with `TS.flatten` exactly?
261+fromFlexSrcType :: T.Canonical -> IO ( Type, Map.Map N.Name Variable )
262+fromFlexSrcType srcType =
263+ do let freeVars = gatherFreeVars srcType Map.empty
264+ freeFlexVars <- Map.traverseWithKey (\name () -> nameToFlex name) freeVars
265+ tipe <- fromSrcType (Map.map VarN freeFlexVars) srcType
266+ return ( tipe, freeFlexVars )
269+fromRigidSrcType :: T.Canonical -> IO ( Type, Map.Map N.Name Variable )
270+fromRigidSrcType srcType =
271+ do let freeVars = gatherFreeVars srcType Map.empty
272+ freeRigidVars <- Map.traverseWithKey (\name () -> nameToRigid name) freeVars
273+ tipe <- fromSrcType (Map.map VarN freeRigidVars) srcType
274+ return ( tipe, freeRigidVars )
277+gatherFreeVars :: T.Canonical -> Map.Map N.Name () -> Map.Map N.Name ()
278+gatherFreeVars tipe dict =
280+ T.Lambda arg result ->
281+ gatherFreeVars result (gatherFreeVars arg dict)
284+ Map.insert name () dict
287+ foldr gatherFreeVars dict args
289+ T.Aliased _ _ args _ ->
290+ foldr gatherFreeVars dict (map snd args)
293+ gatherFreeVars a $ gatherFreeVars b $
294+ foldr gatherFreeVars dict cs
299+ T.Record fields maybeExt ->
302+ Map.foldr gatherFreeVars dict fields
305+ Map.foldr gatherFreeVars (gatherFreeVars ext dict) fields
308+fromSrcType :: Map.Map N.Name Type -> T.Canonical -> IO Type
309+fromSrcType freeVars sourceType =
311+ T.Lambda arg result ->
313+ <$> fromSrcType freeVars arg
314+ <*> fromSrcType freeVars result
317+ return (freeVars ! name)
319+ T.Type home name args ->
320+ AppN home name <$> traverse (fromSrcType freeVars) args
322+ T.Aliased home name args aliasedType ->
323+ do targs <- traverse (traverse (fromSrcType freeVars)) args
324+ AliasN home name targs <$>
326+ T.Filled realType ->
327+ fromSrcType freeVars realType
330+ fromSrcType (Map.fromList targs) realType
334+ <$> fromSrcType freeVars a
335+ <*> fromSrcType freeVars b
336+ <*> traverse (fromSrcType freeVars) cs
341+ T.Record fields maybeExt ->
343+ <$> traverse (fromSrcType freeVars) fields
350+ fromSrcType freeVars ext
248−-- CONVERT TO SOURCE TYPES
354+-- TO SOURCE TYPES
251-- TODO: Attach resulting type to the descriptor so that you
357-- TODO: Attach resulting type to the descriptor so that you
@@ -303,10 +409,10 @@ contentToSrcType variable content =
303 RigidSuper _ name ->
409 RigidSuper _ name ->
304 return (T.Var name)
410 return (T.Var name)
306− Alias name args realVariable ->
412+ Alias home name args realVariable ->
307 do srcArgs <- traverse (traverse variableToSrcType) args
413 do srcArgs <- traverse (traverse variableToSrcType) args
308 srcType <- variableToSrcType realVariable
414 srcType <- variableToSrcType realVariable
309− return (T.Aliased name srcArgs (T.Filled srcType))
415+ return (T.Aliased home name srcArgs (T.Filled srcType))
311 Error name ->
417 Error name ->
312 return (T.Var name)
418 return (T.Var name)
@@ -315,8 +421,8 @@ contentToSrcType variable content =
315termToSrcType :: FlatType -> StateT NameState IO T.Canonical
421termToSrcType :: FlatType -> StateT NameState IO T.Canonical
316termToSrcType term =
422termToSrcType term =
317 case term of
423 case term of
318− App1 name args ->
424+ App1 home name args ->
319− T.Type name <$> traverse variableToSrcType args
425+ T.Type home name <$> traverse variableToSrcType args
321 Fun1 a b ->
427 Fun1 a b ->
@@ -324,15 +430,15 @@ termToSrcType term =
324 <*> variableToSrcType b
430 <*> variableToSrcType b
326 EmptyRecord1 ->
432 EmptyRecord1 ->
327− return $ T.Record [] Nothing
433+ return $ T.Record Map.empty Nothing
329 Record1 fields extension ->
435 Record1 fields extension ->
330− do srcFields <- Map.toList <$> traverse variableToSrcType fields
436+ do srcFields <- traverse variableToSrcType fields
331 srcExt <- T.iteratedDealias <$> variableToSrcType extension
437 srcExt <- T.iteratedDealias <$> variableToSrcType extension
333 case srcExt of
439 case srcExt of
334 T.Record subFields subExt ->
440 T.Record subFields subExt ->
335− T.Record (subFields ++ srcFields) subExt
441+ T.Record (Map.union subFields srcFields) subExt
337 T.Var _ ->
443 T.Var _ ->
338 T.Record srcFields (Just srcExt)
444 T.Record srcFields (Just srcExt)
@@ -340,6 +446,15 @@ termToSrcType term =
341 error "Used toSrcType on a type that is not well-formed"
447 error "Used toSrcType on a type that is not well-formed"
454+ <$> variableToSrcType a
455+ <*> variableToSrcType b
456+ <*> traverse variableToSrcType cs
345-- MANAGE FRESH VARIABLE NAMES
460-- MANAGE FRESH VARIABLE NAMES
@@ -470,23 +585,33 @@ getVarNames var =
470 RigidSuper super name ->
585 RigidSuper super name ->
471 registerName name var (RigidSuper super)
586 registerName name var (RigidSuper super)
473− Alias _ args realVar ->
588+ Alias _ _ args realVar ->
474 do mapM_ (getVarNames . snd) args
589 do mapM_ (getVarNames . snd) args
475 getVarNames realVar
590 getVarNames realVar
477− Structure (App1 _ args) ->
592+ Structure flatType ->
478− mapM_ getVarNames args
595+ mapM_ getVarNames args
480− Structure (Fun1 arg body) ->
597+ Fun1 arg body ->
481− do getVarNames arg
598+ do getVarNames arg
482− getVarNames body
599+ getVarNames body
484− Structure EmptyRecord1 ->
601+ EmptyRecord1 ->
604+ Record1 fields extension ->
605+ do mapM_ getVarNames fields
606+ getVarNames extension
485− return ()
609+ return ()
487− Structure (Record1 fields extension) ->
611+ Tuple1 a b cs ->
488− do mapM_ getVarNames fields
614+ mapM_ getVarNames cs
489− getVarNames extension