@anonymous/IntrepidVacantGraywolf
Haskell

No description

repl talk
Files
  • main.hs
main.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
{- | An EDSL for defining and printing JSON values
-}

import Data.List (intercalate)

----------------
-- JSON Model --
----------------

-- | The JSONValue data type represents a JSON Value
data JSONValue
  = JString String
  | JNumber Double
  | JBool Bool
  | JNull
  | JArray [JSONValue]
  | JObject [NamedValue]

-- | A value with a name
data NamedValue = NamedValue String JSONValue

---------------
-- utilities --
---------------

-- Utility functions for construction a JSON (or: the API)

-- | Create a string
str_ :: String -> JSONValue
str_ = JString

-- | Create a number
num_ :: Double -> JSONValue
num_ = JNumber

-- | The value `true`
true_ :: JSONValue
true_ = JBool True

-- | The value `false`
false_ :: JSONValue
false_ = JBool False

-- | The value `null`
null_ :: JSONValue
null_ = JNull

-- | A function for creating a JS array for a list of `JSONValue`s
arr_ :: [JSONValue] -> JSONValue
arr_ = JArray

-- | A function for creating a JS object from a list of `NamedValues`s
obj_ :: [NamedValue] -> JSONValue
obj_ = JObject

-- | A utility function for field definition in an object
(.=) :: String -> JSONValue -> NamedValue
name .= value = NamedValue name value
-- this defines the associativity (in this case r - right) and the precedence (in this case, 9) of the operator .=
infixr 9 .=

---------------------------------------------
-- Generate a JSON string from a JSONValue --
---------------------------------------------

-- we are going to use the function `show` which can escape strings and convert Int to String

-- | Pretty print a JSON value
ppJSON :: JSONValue -> String
ppJSON jsval = case jsval of
  JString str ->
    show str

  JNumber n ->
    show n

  JBool True ->
    "true"

  JBool False ->
    "false"

  JNull ->
    "null"

  JArray arr ->
    "[ "
      ++ intercalate ", " (map ppJSON arr)
      ++ " ]"

  JObject elems ->
    "{ "
      ++ intercalate ", " (map ppElement elems)
      ++ " }"

  where
    -- | Pretty print a JSON object element, optionally place a comma at the end
    ppElement :: NamedValue -> String
    ppElement (NamedValue str jv') =
      show str ++ ": " ++ ppJSON jv'

----------
-- Main --
----------

main :: IO ()
main = do
  putStrLn (ppJSON links)

links =
  obj_
    [ "language" .= str_ "Haskell"
    , "age" .= num_ 27
    , "fun" .= true_
    , "get_started" .= str_ "https://www.haskell-lang.org/get-started"
    , "learn" .= str_ "http://haskellbook.com"
    , "tools" .= obj_
      [ "hoogle" .= str_ "http://hoogle.haskell.org"
      , "ghcid" .= str_ "https://github.com/ndmitchell/ghcid"
      , "minimal_haskell_emacs" .= str_ "https://github.com/soupi/minimal-haskell-emacs"
      , "atom-haskell" .= str_ "https://atom.io/packages/atom-haskell"
      , "vscode_haskero" .= str_ "https://marketplace.visualstudio.com/items?itemName=Vans.haskero"
      ]
    , "libraries" .= arr_
      [ str_ "http://haskellisseasy.com/"
      , str_ "https://hackage.haskell.org/"
      , str_ "https://stackage.org/"
      ]
    ]

GHCi, version 8.0.1