Skip to content

Instantly share code, notes, and snippets.

@duangsuse
Created April 29, 2019 16:08
Show Gist options
  • Save duangsuse/8f484805cea270edd6d6ae45e2bd6d28 to your computer and use it in GitHub Desktop.
Save duangsuse/8f484805cea270edd6d6ae45e2bd6d28 to your computer and use it in GitHub Desktop.
Json emitter in Haskell
-- | Naive JSON Emitter
module Json where
import Data.Map as Map
import Data.Char as Char
import Text.Printf
type NumJ = Double
data ValueJ
= ObjectJ (Map String ValueJ)
| ArrayJ [ValueJ]
| StringJ String
| NumberJ NumJ
| BoolJ Bool
| NullJ
deriving (Eq, Read)
instance Show ValueJ where
show (ObjectJ map) = "{" ++ Map.foldrWithKey (\k o ac -> show k ++ ":" ++ show o ++ col ac ++ ac) "}" map
where
col "}" = ""
col _ = ","
show (ArrayJ ary) = "[" ++ Prelude.foldr (\o ac -> show o ++ col ac ++ ac) "]" ary
where
col "]" = ""
col _ = ","
show (StringJ str) = "\"" ++ escape str ++ "\""
where
escape ('"' : rs) = '\\' : '"' : escape rs
escape ('\\' : rs) = '\\' : '\\' : escape rs
escape ('/' : rs) = '\\' : '/' : escape rs
escape ('\b' : rs) = '\\' : 'b' : escape rs
escape ('\n' : rs) = '\\' : 'n' : escape rs
escape ('\r' : rs) = '\\' : 'r' : escape rs
escape ('\t' : rs) = '\\' : 't' : escape rs
escape (c : rs) = let
op = if Char.ord c `elem` [0x0020 .. 0x10ffff] then (\_ -> [c]) else ((++ "u") . printf "%04x")
in op c ++ escape rs
escape [] = ""
show (NumberJ num) = show num
show (BoolJ True) = "true"
show (BoolJ False) = "false"
show NullJ = "null"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment