2 ( Type(..), RawType, CanonicalType, PortType(..)
3 , portTypeToType, fieldMap, recordOf, listOf, tupleOf
9import Control.Applicative ((<$>), (<*>))
10import Control.Arrow (second)
12import qualified Data.Map as Map
14import qualified AST.Variable as Var
16import qualified AST.Helpers as Help
17import Text.PrettyPrint as P
23 = Lambda (Type var) (Type var)
26 | App (Type var) [Type var]
27 | Record [(String, Type var)] (Maybe (Type var))
28 | Aliased Var.Canonical [(String, Type var)] (Type var)
47portTypeToType :: PortType Var.Canonical -> CanonicalType
48portTypeToType portType =
49 let makeType name tipe =
50 App (Type (Var.fromModule ["Port"] name)) [tipe]
53 Inbound tipe -> makeType "InboundPort" tipe
54 Internal tipe -> makeType "Port" tipe
55 Outbound tipe -> makeType "OutboundPort" tipe
58fieldMap :: [(String,a)] -> Map.Map String [a]
60 let add r (field,tipe) =
61 Map.insertWith (++) field [tipe] r
63 foldl add Map.empty fields
66recordOf :: [(String, Type var)] -> Type var
71listOf :: RawType -> RawType
73 App (Type (Var.Raw "List")) [tipe]
76tupleOf :: [RawType] -> RawType
78 let name = Var.Raw ("_Tuple" ++ show (length types))
85deepDealias :: Type v -> Type v
87 let go = deepDealias in
96 Record (map (second go) fields) (fmap go ext)
98 Aliased _name args tipe' ->
99 deepDealias (dealias args tipe')
105 App (go f) (map go args)
108dealias :: [(String, Type v)] -> Type v -> Type v
110 replace (Map.fromList args) tipe
113replace :: Map.Map String (Type var) -> Type var -> Type var
115 let go = replace typeTable in
121 Map.findWithDefault t x typeTable
124 Record (map (second go) fields) (fmap go ext)
126 Aliased original args t' ->
127 let typeTable' = foldr Map.delete typeTable (map fst args)
129 Aliased original (map (second go) args) (replace typeTable' t')
135 App (go f) (map go args)
140instance (Pretty var, Var.ToString var) => Pretty (PortType var) where
144 P.text "InboundPort" <+> pretty tipe
147 P.text "Port" <+> pretty tipe
150 P.text "OutboundPort" <+> pretty tipe
153instance (Var.ToString var, Pretty var) => Pretty (Type var) where
157 P.sep [ t, P.sep (map (P.text "->" <+>) ts) ]
159 t:ts = map prettyLambda (collectLambdas tipe)
162 Lambda _ _ -> P.parens (pretty t)
169 let v = Var.toString var
171 P.text (if v == "_Tuple0" then "()" else v)
176 | Help.isTuple (Var.toString name) ->
177 P.parens (P.sep (P.punctuate P.comma (map pretty args)))
179 _ -> P.hang (pretty f) 2 (P.sep (map prettyParens args))
182 case flattenRecord tipe of
188 [ P.cat (zipWith (<+>) (P.lbrace : repeat P.comma) (map prettyField fields))
194 (P.lbrace <+> P.text x <+> P.text "|")
197 [ P.cat (zipWith (<+>) (P.space : repeat P.comma) (map prettyField fields))
201 prettyField (field, tipe) =
202 P.text field <+> P.text ":" <+> pretty tipe
207 if show t' `elem` ["Int", "Float", "String", "Char", "Bool"]
211 Aliased name args _ ->
212 P.hang (pretty name) 2 (P.sep (map (prettyParens . snd) args))
215collectLambdas :: Type var -> [Type var]
219 arg : collectLambdas body
225prettyParens :: (Var.ToString var, Pretty var) => Type var -> Doc
227 parensIf (needed tipe) (pretty tipe)
231 Aliased _ [] _ -> False
233 Aliased _ _ _ -> True
238 | Help.isTuple (Var.toString name) ->
241 App t' [] -> needed t'
248flattenRecord :: Type var -> ( [(String, Type var)], Maybe String )
254 Record fields Nothing ->
257 Record fields (Just ext) ->
258 let (fields',ext') = flattenRecord ext
260 (fields' ++ fields, ext')
266 error "Trying to flatten ill-formed record."
271instance Binary var => Binary (Type var) where
275 putWord8 0 >> put t1 >> put t2
281 putWord8 2 >> put name
284 putWord8 3 >> put t1 >> put t2
287 putWord8 4 >> put fs >> put ext
289 Aliased var args t ->
290 putWord8 5 >> put var >> put args >> put t
295 0 -> Lambda <$> get <*> get
298 3 -> App <$> get <*> get
299 4 -> Record <$> get <*> get
300 5 -> Aliased <$> get <*> get <*> get
301 _ -> error "Error reading a valid type from serialized string"
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