1{-# LANGUAGE OverloadedStrings #-}
2module Elm.Compiler.Type
7import Control.Arrow (second)
8import Data.Aeson ((.:))
9import qualified Data.Aeson as Json
10import qualified Data.Aeson.Types as Json
11import qualified Data.ByteString.Lazy.Char8 as BS
12import qualified Data.Text as Text
13import Text.PrettyPrint as P
15import qualified AST.Helpers as Help
16import qualified AST.Type as Type
17import qualified AST.Variable as Var
18import qualified Parse.Helpers as Parse
19import qualified Parse.Type as Type
20import qualified Reporting.Annotation as A
28 | Record [(String, Type)] (Maybe Type)
33data Context = None | ADT | Function
36toString :: Type -> String
38 P.render (toDoc None tipe)
41toDoc :: Context -> Type -> P.Doc
46 map (toDoc Function) (collectLambdas tipe)
49 P.sep [ t, P.sep (map (P.text "->" <+>) ts) ]
59 P.text (if name == "_Tuple0" then "()" else name)
62 | Help.isTuple name ->
64 [ P.cat (zipWith (<+>) (P.lparen : repeat P.comma) (map (toDoc None) args))
69 let adt = P.hang (P.text name) 2 (P.sep $ map (toDoc ADT) args)
71 case (context, args) of
72 (ADT, _ : _) -> P.parens adt
77 "Somehow ended up with an unexpected type, please post a minimal example that\n"
78 ++ "reproduces this error to <https://github.com/elm-lang/elm-compiler/issues>"
81 case flattenRecord tipe of
87 [ P.cat (zipWith (<+>) (P.lbrace : repeat P.comma) (map prettyField fields))
93 (P.lbrace <+> P.text x <+> P.text "|")
96 [ P.sep (P.punctuate P.comma (map prettyField fields))
101 prettyField (field, tipe) =
102 P.text field <+> P.text ":" <+> toDoc None tipe
105collectLambdas :: Type -> [Type]
108 Lambda arg body -> arg : collectLambdas body
112flattenRecord :: Type -> ( [(String, Type)], Maybe String )
115 Var x -> ([], Just x)
117 Record fields Nothing -> (fields, Nothing)
119 Record fields (Just ext) ->
120 let (fields',ext') = flattenRecord ext
122 (fields' ++ fields, ext')
124 _ -> error "Trying to flatten ill-formed record."
129instance Json.ToJSON Type where
131 Json.String (Text.unwords (Text.words (Text.pack (toString tipe))))
134instance Json.FromJSON Type where
139 "Trying to decode a type string, but could not handle this value:\n"
140 ++ BS.unpack (Json.encode value)
144 either failure (return . fromRawType)
145 (Parse.iParse Type.expr (Text.unpack text))
154fromObject :: Json.Object -> Json.Parser Type
156 do tag <- obj .: "tag"
157 case (tag :: String) of
159 Lambda <$> obj .: "in" <*> obj .: "out"
162 Var <$> obj .: "name"
165 Type <$> obj .: "name"
168 App <$> obj .: "func" <*> obj .: "args"
171 Record <$> obj .: "fields" <*> obj .: "extension"
174 fail $ "Error when decoding type with tag: " ++ tag
177fromRawType :: Type.Raw -> Type
178fromRawType (A.A _ astType) =
180 Type.RLambda t1 t2 ->
181 Lambda (fromRawType t1) (fromRawType t2)
187 Type (Var.toString var)
190 App (fromRawType t) (map fromRawType ts)
192 Type.RRecord fields ext ->
193 Record (map (second fromRawType) fields) (fmap fromRawType ext)
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