@@ -9,11 +9,10 @@ import Control.Arrow (second)
9import Data.Aeson ((.:), (.=))
9import Data.Aeson ((.:), (.=))
10import qualified Data.Aeson as Json
10import qualified Data.Aeson as Json
11import qualified Data.ByteString.Lazy.Char8 as BS
11import qualified Data.ByteString.Lazy.Char8 as BS
12−import qualified Data.List as List
13import qualified Data.Text as Text
12import qualified Data.Text as Text
13+import Text.PrettyPrint as P
15import qualified AST.Helpers as Help
15import qualified AST.Helpers as Help
16−import Elm.Utils ((|>))
@@ -31,66 +30,87 @@ data Context = None | ADT | Function
32toString :: Type -> String
31toString :: Type -> String
33toString tipe =
32toString tipe =
34− toStringHelp None tipe
33+ P.render (toDoc None tipe)
37−toStringHelp :: Context -> Type -> String
36+toDoc :: Context -> Type -> P.Doc
38−toStringHelp context tipe =
37+toDoc context tipe =
39 case tipe of
38 case tipe of
40− Lambda t1 t2 ->
39+ Lambda _ _ ->
41− let string = toStringHelp Function t1 ++ " -> " ++ toString t2
40+ let t:ts =
41+ map (toDoc Function) (collectLambdas tipe)
44+ P.sep [ t, P.sep (map (P.text "->" <+>) ts) ]
43 case context of
46 case context of
44− None -> string
47+ None -> lambda
45− _ -> parens string
48+ _ -> P.parens lambda
47− Var name -> name
50+ Var name ->
49− Type name -> name
53+ Type name ->
54+ P.text (if name == "_Tuple0" then "()" else name)
51 App (Type name) args
56 App (Type name) args
52 | Help.isTuple name ->
57 | Help.isTuple name ->
53− map toString args
58+ P.sep
54− |> List.intercalate ", "
59+ [ P.cat (zipWith (<+>) (P.lparen : repeat P.comma) (map (toDoc None) args))
55− |> parens
60+ , P.rparen
57 | otherwise ->
63 | otherwise ->
58− let string = name ++ spacePrefix (map (toStringHelp ADT) args)
64+ let adt = P.hang (P.text name) 2 (P.sep $ map (toDoc ADT) args)
60 case (context, args) of
66 case (context, args) of
61− (ADT, _ : _) -> parens string
67+ (ADT, _ : _) -> P.parens adt
62− _ -> string
68+ _ -> adt
64− Record fields maybeExtension ->
70+ Record _ _ ->
65− let viewField (key, value) =
71+ case flattenRecord tipe of
66− key ++ " : " ++ toString value
68− viewExtension maybeType =
70− Nothing -> ""
72+ ([], Nothing) ->
71− Just t -> toString t ++ " | "
73+ P.text "{}"
73− sandwich "{ " " }" $
75+ (fields, Nothing) ->
75− [ viewExtension maybeExtension
77+ [ P.cat (zipWith (<+>) (P.lbrace : repeat P.comma) (map prettyField fields))
76− , map viewField fields
78+ , P.rbrace
77− |> List.intercalate ", "
83+ (P.lbrace <+> P.text x <+> P.text "|")
86+ [ P.cat (zipWith (<+>) (P.space : repeat P.comma) (map prettyField fields))
90+ prettyField (field, tipe) =
91+ P.text field <+> P.text ":" <+> toDoc None tipe
94+collectLambdas :: Type -> [Type]
97+ Lambda arg body -> arg : collectLambdas body
81−parens :: String -> String
83− sandwich "(" ")" string
101+flattenRecord :: Type -> ( [(String, Type)], Maybe String )
104+ Var x -> ([], Just x)
86−spacePrefix :: [String] -> String
106+ Record fields Nothing -> (fields, Nothing)
88− concatMap (" " ++) strings
108+ Record fields (Just ext) ->
109+ let (fields',ext') = flattenRecord ext
111+ (fields' ++ fields, ext')
91−sandwich :: String -> String -> String -> String
113+ _ -> error "Trying to flatten ill-formed record."
92−sandwich start stop string =
93− start ++ string ++ stop
96-- JSON for TYPE
116-- JSON for TYPE