Mercurial > meta
comparison json.ur @ 23:9d6b931fbd13
Implement JSON type class for recursive datatypes, using Mu combinator.
author | Edward Z. Yang <ezyang@mit.edu> |
---|---|
date | Wed, 02 May 2012 11:47:37 -0400 |
parents | 8de201d70b91 |
children | 7530b2b54353 |
comparison
equal
deleted
inserted
replaced
22:8de201d70b91 | 23:9d6b931fbd13 |
---|---|
23 in | 23 in |
24 skip 0 | 24 skip 0 |
25 end | 25 end |
26 | 26 |
27 fun toJson [a] (j : json a) : a -> string = j.ToJson | 27 fun toJson [a] (j : json a) : a -> string = j.ToJson |
28 fun fromJson' [a] (j : json a) : string -> a * string = j.FromJson | |
28 | 29 |
29 fun fromJson [a] (j : json a) (s : string) : a = | 30 fun fromJson [a] (j : json a) (s : string) : a = |
30 let | 31 let |
31 val (v, s') = j.FromJson (skipSpaces s) | 32 val (v, s') = j.FromJson (skipSpaces s) |
32 in | 33 in |
276 FromJson = fn s => | 277 FromJson = fn s => |
277 if String.length s = 0 || String.sub s 0 <> #"{" then | 278 if String.length s = 0 || String.sub s 0 <> #"{" then |
278 error <xml>JSON variant doesn't begin with brace</xml> | 279 error <xml>JSON variant doesn't begin with brace</xml> |
279 else | 280 else |
280 let | 281 let |
281 val (name, s') = unescape s | 282 val (name, s') = unescape (skipSpaces (String.suffix s 1)) |
282 val s' = skipSpaces s' | 283 val s' = skipSpaces s' |
283 val s' = if String.length s' = 0 || String.sub s' 0 <> #":" then | 284 val s' = if String.length s' = 0 || String.sub s' 0 <> #":" then |
284 error <xml>No colon after JSON object field name</xml> | 285 error <xml>No colon after JSON object field name</xml> |
285 else | 286 else |
286 skipSpaces (String.substring s' {Start = 1, Len = String.length s' - 1}) | 287 skipSpaces (String.substring s' {Start = 1, Len = String.length s' - 1}) |
312 else error <xml>Junk after JSON value in object</xml> | 313 else error <xml>Junk after JSON value in object</xml> |
313 end | 314 end |
314 } | 315 } |
315 | 316 |
316 val json_unit : json unit = json_record {} {} | 317 val json_unit : json unit = json_record {} {} |
318 | |
319 functor Recursive (M : sig | |
320 con t :: Type -> Type | |
321 val json_t : a ::: Type -> json a -> json (t a) | |
322 end) = struct | |
323 open M | |
324 | |
325 datatype r = Rec of t r | |
326 | |
327 fun rTo (Rec x) = (json_t {ToJson = rTo, | |
328 FromJson = fn _ => error <xml>Tried to FromJson in ToJson!</xml>}).ToJson x | |
329 | |
330 fun rFrom s = | |
331 let | |
332 val (x, s') = (json_t {ToJson = fn _ => error <xml>Tried to ToJson in FromJson!</xml>, | |
333 FromJson = rFrom}).FromJson s | |
334 in | |
335 (Rec x, s') | |
336 end | |
337 | |
338 val json_r = {ToJson = rTo, FromJson = rFrom} | |
339 end |