2 ( Type(..), RawType, CanonicalType
3 , PortType(..), PortDirection(..)
4 , fieldMap, recordOf, listOf, tupleOf
10import Control.Applicative ((<$>), (<*>))
11import Control.Arrow (second)
13import qualified Data.Map as Map
15import qualified AST.Variable as Var
17import qualified AST.Helpers as Help
18import Text.PrettyPrint as P
24 = Lambda (Type var) (Type var)
27 | App (Type var) [Type var]
28 | Record [(String, Type var)] (Maybe (Type var))
29 | Aliased Var.Canonical [(String, Type var)] (Type var)
41data PortType var = PortType
42 { direction :: PortDirection var
55fieldMap :: [(String,a)] -> Map.Map String [a]
57 let add r (field,tipe) =
58 Map.insertWith (++) field [tipe] r
60 foldl add Map.empty fields
63recordOf :: [(String, Type var)] -> Type var
68listOf :: RawType -> RawType
70 App (Type (Var.Raw "List")) [tipe]
73tupleOf :: [RawType] -> RawType
75 let name = Var.Raw ("_Tuple" ++ show (length types))
82deepDealias :: Type v -> Type v
84 let go = deepDealias in
93 Record (map (second go) fields) (fmap go ext)
95 Aliased _name args tipe' ->
96 deepDealias (dealias args tipe')
102 App (go f) (map go args)
105dealias :: [(String, Type v)] -> Type v -> Type v
107 replace (Map.fromList args) tipe
110replace :: Map.Map String (Type var) -> Type var -> Type var
112 let go = replace typeTable in
118 Map.findWithDefault t x typeTable
121 Record (map (second go) fields) (fmap go ext)
123 Aliased original args t' ->
124 let typeTable' = foldr Map.delete typeTable (map fst args)
126 Aliased original (map (second go) args) (replace typeTable' t')
132 App (go f) (map go args)
137instance (Pretty var, Var.ToString var) => Pretty (PortType var) where
139 pretty (tipe portType)
142instance (Var.ToString var, Pretty var) => Pretty (Type var) where
146 P.sep [ t, P.sep (map (P.text "->" <+>) ts) ]
148 t:ts = map prettyLambda (collectLambdas tipe)
151 Lambda _ _ -> P.parens (pretty t)
158 let v = Var.toString var
160 P.text (if v == "_Tuple0" then "()" else v)
165 | Help.isTuple (Var.toString name) ->
166 P.parens (P.sep (P.punctuate P.comma (map pretty args)))
168 _ -> P.hang (pretty f) 2 (P.sep (map prettyParens args))
171 case flattenRecord tipe of
177 [ P.cat (zipWith (<+>) (P.lbrace : repeat P.comma) (map prettyField fields))
183 (P.lbrace <+> P.text x <+> P.text "|")
186 [ P.cat (zipWith (<+>) (P.space : repeat P.comma) (map prettyField fields))
190 prettyField (field, tipe) =
191 P.text field <+> P.text ":" <+> pretty tipe
196 if show t' `elem` ["Int", "Float", "String", "Char", "Bool"]
200 Aliased name args _ ->
201 P.hang (pretty name) 2 (P.sep (map (prettyParens . snd) args))
204collectLambdas :: Type var -> [Type var]
208 arg : collectLambdas body
214prettyParens :: (Var.ToString var, Pretty var) => Type var -> Doc
216 parensIf (needed tipe) (pretty tipe)
220 Aliased _ [] _ -> False
222 Aliased _ _ _ -> True
227 | Help.isTuple (Var.toString name) ->
230 App t' [] -> needed t'
237flattenRecord :: Type var -> ( [(String, Type var)], Maybe String )
243 Record fields Nothing ->
246 Record fields (Just ext) ->
247 let (fields',ext') = flattenRecord ext
249 (fields' ++ fields, ext')
255 error "Trying to flatten ill-formed record."
260instance Binary var => Binary (Type var) where
264 putWord8 0 >> put t1 >> put t2
270 putWord8 2 >> put name
273 putWord8 3 >> put t1 >> put t2
276 putWord8 4 >> put fs >> put ext
278 Aliased var args t ->
279 putWord8 5 >> put var >> put args >> put t
284 0 -> Lambda <$> get <*> get
287 3 -> App <$> get <*> get
288 4 -> Record <$> get <*> get
289 5 -> Aliased <$> get <*> get <*> get
290 _ -> 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