1{-# OPTIONS_GHC -Wall #-}
2{-# LANGUAGE OverloadedStrings #-}
3module Type.Constrain.Module
9import qualified Data.Map.Strict as Map
10import qualified Data.Name as Name
12import qualified AST.Canonical as Can
13import qualified Elm.ModuleName as ModuleName
14import qualified Reporting.Annotation as A
15import qualified Reporting.Error.Type as E
16import qualified Type.Constrain.Expression as Expr
17import qualified Type.Instantiate as Instantiate
18import Type.Type (Type(..), Constraint(..), (==>), mkFlexVar, nameToRigid, never)
25constrain :: Can.Module -> IO Constraint
26constrain (Can.Module home _ decls _ _ _ effects) =
29 constrainDecls decls CSaveTheEnvironment
32 Map.foldrWithKey letPort (constrainDecls decls CSaveTheEnvironment) ports
34 Can.Manager r0 r1 r2 manager ->
37 letCmd home cmdName =<<
38 constrainDecls decls =<< constrainEffects home r0 r1 r2 manager
41 letSub home subName =<<
42 constrainDecls decls =<< constrainEffects home r0 r1 r2 manager
44 Can.Fx cmdName subName ->
45 letCmd home cmdName =<<
46 letSub home subName =<<
47 constrainDecls decls =<< constrainEffects home r0 r1 r2 manager
51-- CONSTRAIN DECLARATIONS
54constrainDecls :: Can.Decls -> Constraint -> IO Constraint
55constrainDecls decls finalConstraint =
57 Can.Declare def otherDecls ->
58 Expr.constrainDef Map.empty def =<< constrainDecls otherDecls finalConstraint
60 Can.DeclareRec def defs otherDecls ->
61 Expr.constrainRecursiveDefs Map.empty (def:defs) =<< constrainDecls otherDecls finalConstraint
63 Can.SaveTheEnvironment ->
64 return finalConstraint
71letPort :: Name.Name -> Can.Port -> IO Constraint -> IO Constraint
72letPort name port_ makeConstraint =
74 Can.Incoming freeVars _ srcType ->
75 do vars <- Map.traverseWithKey (\k _ -> nameToRigid k) freeVars
76 tipe <- Instantiate.fromSrcType (Map.map VarN vars) srcType
77 let header = Map.singleton name (A.At A.zero tipe)
78 CLet (Map.elems vars) [] header CTrue <$> makeConstraint
80 Can.Outgoing freeVars _ srcType ->
81 do vars <- Map.traverseWithKey (\k _ -> nameToRigid k) freeVars
82 tipe <- Instantiate.fromSrcType (Map.map VarN vars) srcType
83 let header = Map.singleton name (A.At A.zero tipe)
84 CLet (Map.elems vars) [] header CTrue <$> makeConstraint
88-- EFFECT MANAGER HELPERS
91letCmd :: ModuleName.Canonical -> Name.Name -> Constraint -> IO Constraint
92letCmd home tipe constraint =
93 do msgVar <- mkFlexVar
95 let cmdType = FunN (AppN home tipe [msg]) (AppN ModuleName.cmd Name.cmd [msg])
96 let header = Map.singleton "command" (A.At A.zero cmdType)
97 return $ CLet [msgVar] [] header CTrue constraint
100letSub :: ModuleName.Canonical -> Name.Name -> Constraint -> IO Constraint
101letSub home tipe constraint =
102 do msgVar <- mkFlexVar
103 let msg = VarN msgVar
104 let subType = FunN (AppN home tipe [msg]) (AppN ModuleName.sub Name.sub [msg])
105 let header = Map.singleton "subscription" (A.At A.zero subType)
106 return $ CLet [msgVar] [] header CTrue constraint
109constrainEffects :: ModuleName.Canonical -> A.Region -> A.Region -> A.Region -> Can.Manager -> IO Constraint
110constrainEffects home r0 r1 r2 manager =
127 let onSelfMsg = router msg2 self2 ==> self2 ==> state2 ==> task state2
130 Can.Cmd cmd -> router msg1 self1 ==> effectList home cmd msg1 ==> state1 ==> task state1
131 Can.Sub sub -> router msg1 self1 ==> effectList home sub msg1 ==> state1 ==> task state1
132 Can.Fx cmd sub -> router msg1 self1 ==> effectList home cmd msg1 ==> effectList home sub msg1 ==> state1 ==> task state1
136 [ CLocal r0 "init" (E.NoExpectation (task state0))
137 , CLocal r1 "onEffects" (E.NoExpectation onEffects)
138 , CLocal r2 "onSelfMsg" (E.NoExpectation onSelfMsg)
139 , CEqual r1 E.Effects state0 (E.NoExpectation state1)
140 , CEqual r2 E.Effects state0 (E.NoExpectation state2)
141 , CEqual r2 E.Effects self1 (E.NoExpectation self2)
144 CLet [] [s0,s1,s2,m1,m2,sm1,sm2] Map.empty effectCons <$>
147 checkMap "cmdMap" home cmd CSaveTheEnvironment
150 checkMap "subMap" home sub CSaveTheEnvironment
153 checkMap "cmdMap" home cmd =<<
154 checkMap "subMap" home sub CSaveTheEnvironment
157effectList :: ModuleName.Canonical -> Name.Name -> Type -> Type
158effectList home name msg =
159 AppN ModuleName.list Name.list [AppN home name [msg]]
164 AppN ModuleName.platform Name.task [ never, answer ]
167router :: Type -> Type -> Type
169 AppN ModuleName.platform Name.router [ msg, self ]
172checkMap :: Name.Name -> ModuleName.Canonical -> Name.Name -> Constraint -> IO Constraint
173checkMap name home tipe constraint =
176 let mapType = toMapType home tipe (VarN a) (VarN b)
177 let mapCon = CLocal A.zero name (E.NoExpectation mapType)
178 return $ CLet [a,b] [] Map.empty mapCon constraint
181toMapType :: ModuleName.Canonical -> Name.Name -> Type -> Type -> Type
182toMapType home tipe a b =
183 (a ==> b) ==> AppN home tipe [a] ==> AppN home tipe [b]
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