-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathJSONClass.hs
More file actions
76 lines (57 loc) · 2.05 KB
/
JSONClass.hs
File metadata and controls
76 lines (57 loc) · 2.05 KB
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
-- file: ch06/JSONClass.hs
module JSONClass where
type JSONError = String
newtype JAry a = JAry {
fromJAry :: [a]
} deriving (Eq, Ord, Show)
newtype JObj a = JObj {
fromJObj :: [(String, a)]
} deriving (Eq, Ord, Show)
class JSON a where
toJValue :: a -> JValue
fromJValue :: JValue -> Either JSONError a
data JValue = JString String
| JNumber Double
| JBool Bool
| JNull
| JObject (JObj JValue) -- was [(String, JValue)]
| JArray (JAry JValue) -- was [JValue]
deriving (Eq, Ord, Show)
---------------------------------------------------------
instance (JSON a) => JSON (JAry a) where
-- fromJValue :: (JSON a) => JValue -> Either JSONError (JAry a)
fromJValue (JArray (JAry a)) = whenRight JAry (mapEithers fromJValue a)
where whenRight :: (b -> c) -> Either a b -> Either a c
whenRight _ (Left err) = Left err
whenRight f (Right a) = Right (f a)
mapEithers :: (a -> Either b c) -> [a] -> Either b [c]
mapEithers f (x:xs) = case mapEithers f xs of
Left err -> Left err
Right ys -> case f x of
Left err -> Left err
Right y -> Right (y:ys)
mapEithers _ _ = Right []
fromJValue _ = Left "not a JSON array"
-- toJValue :: (JSON a) => JAry a -> JValue
toJValue = JArray . JAry . map toJValue . fromJAry
--import Control.Arrow (second)
instance (JSON a) => JSON (JObj a) where
toJValue = JObject . JObj . map (second toJValue) . fromJObj
where second :: (b -> c) -> (a, b) -> (a, c)
second f (a,b) = (a, f b)
fromJValue (JObject (JObj o)) = whenRight JObj (mapEithers unwrap o)
where unwrap (k,v) = whenRight ((,) k) (fromJValue v)
whenRight :: (b -> c) -> Either a b -> Either a c
whenRight _ (Left err) = Left err
whenRight f (Right a) = Right (f a)
mapEithers :: (a -> Either b c) -> [a] -> Either b [c]
mapEithers f (x:xs) = case mapEithers f xs of
Left err -> Left err
Right ys -> case f x of
Left err -> Left err
Right y -> Right (y:ys)
mapEithers _ _ = Right []
fromJValue _ = Left "not a JSON object"
instance JSON JValue where
toJValue jv = id jv
fromJValue jv = Right jv