2 ( Type(..), RawType, CanonicalType
3 , 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)
40fieldMap :: [(String,a)] -> Map.Map String [a]
42 let add r (field,tipe) =
43 Map.insertWith (++) field [tipe] r
45 foldl add Map.empty fields
48recordOf :: [(String, Type var)] -> Type var
53listOf :: RawType -> RawType
55 App (Type (Var.Raw "List")) [tipe]
58tupleOf :: [RawType] -> RawType
60 let name = Var.Raw ("_Tuple" ++ show (length types))
67deepDealias :: Type v -> Type v
69 let go = deepDealias in
78 Record (map (second go) fields) (fmap go ext)
80 Aliased _name args tipe' ->
81 deepDealias (dealias args tipe')
87 App (go f) (map go args)
90dealias :: [(String, Type v)] -> Type v -> Type v
92 replace (Map.fromList args) tipe
95replace :: Map.Map String (Type var) -> Type var -> Type var
97 let go = replace typeTable in
103 Map.findWithDefault t x typeTable
106 Record (map (second go) fields) (fmap go ext)
108 Aliased original args t' ->
109 let typeTable' = foldr Map.delete typeTable (map fst args)
111 Aliased original (map (second go) args) (replace typeTable' t')
117 App (go f) (map go args)
122instance (Var.ToString var, Pretty var) => Pretty (Type var) where
126 P.sep [ t, P.sep (map (P.text "->" <+>) ts) ]
128 t:ts = map prettyLambda (collectLambdas tipe)
131 Lambda _ _ -> P.parens (pretty t)
138 let v = Var.toString var
140 P.text (if v == "_Tuple0" then "()" else v)
145 | Help.isTuple (Var.toString name) ->
146 P.parens (P.sep (P.punctuate P.comma (map pretty args)))
148 _ -> P.hang (pretty f) 2 (P.sep (map prettyParens args))
151 case flattenRecord tipe of
157 [ P.cat (zipWith (<+>) (P.lbrace : repeat P.comma) (map prettyField fields))
163 (P.lbrace <+> P.text x <+> P.text "|")
166 [ P.cat (zipWith (<+>) (P.space : repeat P.comma) (map prettyField fields))
170 prettyField (field, tipe) =
171 P.text field <+> P.text ":" <+> pretty tipe
176 if show t' `elem` ["Int", "Float", "String", "Char", "Bool"]
180 Aliased name args _ ->
181 P.hang (pretty name) 2 (P.sep (map (prettyParens . snd) args))
184collectLambdas :: Type var -> [Type var]
188 arg : collectLambdas body
194prettyParens :: (Var.ToString var, Pretty var) => Type var -> Doc
196 parensIf (needed tipe) (pretty tipe)
200 Aliased _ [] _ -> False
202 Aliased _ _ _ -> True
207 | Help.isTuple (Var.toString name) ->
210 App t' [] -> needed t'
217flattenRecord :: Type var -> ( [(String, Type var)], Maybe String )
223 Record fields Nothing ->
226 Record fields (Just ext) ->
227 let (fields',ext') = flattenRecord ext
229 (fields' ++ fields, ext')
235 error "Trying to flatten ill-formed record."
240instance Binary var => Binary (Type var) where
244 putWord8 0 >> put t1 >> put t2
250 putWord8 2 >> put name
253 putWord8 3 >> put t1 >> put t2
256 putWord8 4 >> put fs >> put ext
258 Aliased var args t ->
259 putWord8 5 >> put var >> put args >> put t
264 0 -> Lambda <$> get <*> get
267 3 -> App <$> get <*> get
268 4 -> Record <$> get <*> get
269 5 -> Aliased <$> get <*> get <*> get
270 _ -> 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