1{-# OPTIONS_GHC -Wall #-}
2{-# LANGUAGE OverloadedStrings #-}
3module Elm.Compiler.Type
9import Control.Arrow ((***))
10import Data.Aeson ((.:), (.=))
11import qualified Data.Aeson as Json
12import qualified Data.Aeson.Types as Json
13import qualified Data.ByteString.Lazy.Char8 as BS
14import qualified Data.Text as Text
15import Data.Text (Text)
16import Text.PrettyPrint as P
18import qualified AST.Helpers as Help
19import qualified AST.Type as Type
20import qualified AST.Variable as Var
21import qualified Parse.Helpers as Parse
22import qualified Parse.Type as Type
23import qualified Reporting.Annotation as A
32 | Record [(Text, Type)] (Maybe Type)
38 , _aliases :: [( Text, [Text], Type )]
39 , _unions :: [( Text, [Text], [(Text, [Type])] )]
47data Context = None | ADT | Function
50toString :: Type -> String
52 P.render (toDoc None tipe)
55toDoc :: Context -> Type -> P.Doc
60 map (toDoc Function) (collectLambdas tipe)
63 P.sep [ t, P.sep (map (P.text "->" <+>) ts) ]
70 P.text (Text.unpack name)
73 P.text (Text.unpack (if name == "_Tuple0" then "()" else name))
75 App (Type name) args ->
76 if name == "_Tuple0" then
79 else if Help.isTuple name then
81 [ P.cat (zipWith (<+>) (P.lparen : repeat P.comma) (map (toDoc None) args))
89 (P.text (Text.unpack name))
91 (P.sep $ map (toDoc ADT) args)
93 case (context, args) of
94 (ADT, _ : _) -> P.parens application
99 "Somehow ended up with an unexpected type, please post a minimal example that\n"
100 ++ "reproduces this error to <https://github.com/elm-lang/elm-compiler/issues>"
103 case flattenRecord tipe of
109 [ P.cat (zipWith (<+>) (P.lbrace : repeat P.comma) (map prettyField fields))
115 (P.lbrace <+> P.text (Text.unpack x) <+> P.text "|")
118 [ P.sep (P.punctuate P.comma (map prettyField fields))
123 prettyField (field, fieldType) =
124 P.text (Text.unpack field) <+> P.text ":" <+> toDoc None fieldType
127collectLambdas :: Type -> [Type]
130 Lambda arg body -> arg : collectLambdas body
134flattenRecord :: Type -> ( [(Text, Type)], Maybe Text )
140 Record fields Nothing ->
143 Record fields (Just ext) ->
144 let (fields',ext') = flattenRecord ext
146 (fields' ++ fields, ext')
149 error "Trying to flatten ill-formed record."
156instance Json.ToJSON Type where
158 Json.String (Text.unwords (Text.words (Text.pack (toString tipe))))
161instance Json.FromJSON Type where
166 "Trying to decode a type string, but could not handle this value:\n"
167 ++ BS.unpack (Json.encode value)
171 case Parse.run Type.expression (Text.replace "'" "_" txt) of
175 Right (tipe, _, _) ->
176 return (fromRawType tipe)
185fromObject :: Json.Object -> Json.Parser Type
187 do tag <- obj .: "tag"
188 case (tag :: String) of
190 Lambda <$> obj .: "in" <*> obj .: "out"
193 Var <$> obj .: "name"
196 Type <$> obj .: "name"
199 App <$> obj .: "func" <*> obj .: "args"
202 Record <$> obj .: "fields" <*> obj .: "extension"
205 fail $ "Error when decoding type with tag: " ++ tag
208fromRawType :: Type.Raw -> Type
209fromRawType (A.A _ astType) =
211 Type.RLambda t1 t2 ->
212 Lambda (fromRawType t1) (fromRawType t2)
218 Type (Var.rawToText var)
221 App (fromRawType t) (map fromRawType ts)
223 Type.RRecord fields ext ->
224 Record (map (A.drop *** fromRawType) fields) (fmap fromRawType ext)
231instance Json.ToJSON Program where
232 toJSON (Program msg aliases unions) =
235 , "aliases" .= Json.object (map toAliasField aliases)
236 , "unions" .= Json.object (map toUnionField unions)
240toAliasField :: ( Text, [Text], Type ) -> Json.Pair
241toAliasField ( name, args, tipe ) =
248toUnionField :: ( Text, [Text], [(Text, [Type])] ) -> Json.Pair
249toUnionField ( name, args, constructors ) =
252 , "tags" .= Json.object (map toCtorObject constructors)
256toCtorObject :: (Text, [Type]) -> Json.Pair
257toCtorObject (name, args) =
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