The JSONDecode structure implements combinators for decoding JSON values.
The design is based on
Elm's JSON.Decode module.
Synopsis
signature JSON_DECODE
structure JSONDecode : JSON_DECODE
Interface
exception JSONError of exn * JSON.value
exception NotBool
exception NotInt
exception NotNumber
exception NotString
exception NotObject
exception FieldNotFound of string
exception NotArray
exception ArrayBounds of int
val exnMessage : exn -> string
type 'a decoder
val decode : 'a decoder -> JSON.value -> 'a
val decodeString : 'a decoder -> string -> 'a
val decodeFile : 'a decoder -> string -> 'a
val bool : bool decoder
val int : int decoder
val intInf : IntInf.int decoder
val number : Real64.real decoder
val string : string decoder
val null : 'a -> 'a decoder
val raw : JSON.value decoder
val nullable : 'a decoder -> 'a option decoder
val try : 'a decoder -> 'a option decoder
val seq : 'a decoder -> ('a -> 'b) decoder -> 'b decoder
val field : string -> 'a decoder -> 'a decoder
val reqField : string -> 'a decoder -> ('a -> 'b) decoder -> 'b decoder
val optField : string -> 'a decoder -> ('a option -> 'b) decoder -> 'b decoder
val dfltField : string -> 'a decoder -> 'a -> ('a -> 'b) decoder -> 'b decoder
val array : 'a decoder -> 'a list decoder
val sub : int -> 'a decoder -> 'a decoder
val at : JSONUtil.path -> 'a decoder -> 'a decoder
val succeed : 'a -> 'a decoder
val fail : string -> 'a decoder
val andThen : ('a -> 'b decoder) -> 'a decoder -> 'b decoder
val orElse : 'a decoder * 'a decoder -> 'a decoder
val choose : 'a decoder list -> 'a decoder
val map : ('a -> 'b) -> 'a decoder -> 'b decoder
val map2 : ('a * 'b -> 'res)
-> ('a decoder * 'b decoder)
-> 'res decoder
val map3 : ('a * 'b * 'c -> 'res)
-> ('a decoder * 'b decoder * 'c decoder)
-> 'res decoder
val map4 : ('a * 'b * 'c * 'd -> 'res)
-> ('a decoder * 'b decoder * 'c decoder * 'd decoder)
-> 'res decoder
val tuple2 : ('a decoder * 'b decoder) -> ('a * 'b) decoder
val tuple3 : ('a decoder * 'b decoder * 'c decoder) -> ('a * 'b * 'c) decoder
val tuple4 : ('a decoder * 'b decoder * 'c decoder * 'd decoder)
-> ('a * 'b * 'c * 'd) decoder
val delay : (unit -> 'a decoder) -> 'a decoder
Description
exception JSONError of exn * JSON.value-
raised when an error is detected during processing of a JSON value. The first argument, which is one of the exceptions described below, details the type of error and the second argument is the value that was being processed at the point of the error.
exception NotNull of JSON.value-
used by the
nulldecoder when the argument is not the JSONnullvalue. exception NotBool of JSON.value-
used by the
booldecode when the argument is not a JSON boolean. This exception is the same asJSONUtil.NotBool. exception NotInt of JSON.value-
used by the
intandintInfdecoders when the argument is not a JSON integer number. This exception is the same asJSONUtil.NotInt. exception NotNumber of JSON.value-
used by the
numberdecoder when the argument is not a JSON number. This exception is the same asJSONUtil.NotNumber. exception NotString of JSON.value-
used by the
stringdecoder when the argument is not a JSON string. This exception is the same asJSONUtil.NotString. exception NotObject of JSON.value-
used by the
fielddecoder when the argument is not a JSON object. This exception is the same asJSONUtil.NotObject. exception FieldNotFound of JSON.value * string-
This exception is used by the
fielddecoder when the given field is not found in an object. This exception is the same asJSONUtil.FieldNotFound. exception NotArray of JSON.value-
This exception is used by the
arraydecoder when the argument is not a JSON array. This exception is the same asJSONUtil.NotArray. exception ArrayBounds of JSON.value * int-
This exception is used when access to an array value is out of bounds. This exception is the same as
JSONUtil.ArrayBounds. val exnMessage : exn -> string-
exnMessage exnreturns an error-message string for the exception valueexn. This function produces specialized messages for theJSONErrorwrapped around the other exceptions defined in this structure (or theFailexception). It falls back to the General.exnMessage function for other exceptions. type 'a decoder'-
the type of a decoder that decodes a JSON value to a value of type
'a. val decode : 'a decoder -> JSON.value -> 'a-
decode d jvdecodes the JSON valuejvusing the decoderd. Failure to decode will be signaled by raising an exception that depends on the decoder and value. val decodeString : 'a decoder -> string -> 'a-
decode d sdecodes the JSON value that results from parsing the strings. val decodeFile : 'a decoder -> string -> 'a-
decode d fdecodes the JSON value that results from parsing the filef. val bool : bool decoder-
decodes a JSON Boolean value. This decoder raises the exception value
JSONError(NotBool, jv)if the valuejvis not a JSON Boolean. val int : int decoder-
decodes a JSON integer value. This decoder raises the exception value
JSONError(NotInt, jv)if the argumentjvis not a JSON integer value and theOverflowexception if the integer is too large to be represented as anInt.int. val intInf : IntInf.int decoder-
decodes a JSON integer value. This decoder raises the exception value
JSONError(NotInt, jv)if the argumentjvis not a JSON integer value. val number : Real64.real decoder-
decodes a JSON number value. This decoder raises the exception value
JSONError(NotNumber, jv)if the valuejvis not a JSON number. val string : string decoder-
decodes a JSON string value. This decoder raises the exception value
JSONError(NotString, jv)if the argumentjvis not a JSON string. val null : 'a -> 'a decoder-
null vreturns a decoder for the JSONnullvalue. When used to decode anullvalue, it will return its argumentv; otherwise it will raise the exception valueJSONError(NotNull, jv)when the argumentjvis not a JSON null value. val raw : JSON.value decoder-
this decoder returns the raw JSON value that it is applied to (i.e., it is the identity decoder).
val nullable : 'a decoder -> 'a option decoder-
nullable dreturns a decoder that mapsnulltoNONEand otherwise appliesSOMEto the result of decoding the value using the decoderd. val try : 'a decoder -> 'a option decoder-
try dreturns a decoder that attempts to decode its argument using the decoderd. If it fails, thenNONEis returned. Otherwise,SOMEis applied to the result od decoding the value. val seq : 'a decoder → ('a -> 'b) decoder -> 'b decoder-
seq d ksequences decoding operations in a continuation-passing style. val field : string -> 'a decoder -> 'a decoder-
field lab dreturns a decoder that decodes the object field with the labellabusing the decoderd. It will raise the exception valueJSONError(NotObject, v)when the argumentvis not a JSON object and the exception valueJSONError(FieldNotFound lab, v), whenvdoes not have a field with the specified label. val reqField : string -> 'a decoder -> ('a -> 'b) decoder -> 'b decoder-
reqField lab d kreturns a decoder for a required object field that can be sequenced in a continuation-passing style (it is equivalent toseq (field lab d) k). It will raise the exception valueJSONError(NotObject, v)when the argumentvis not a JSON object and the exception valueJSONError(FieldNotFound lab, v)whenvdoes not have a field with the specified label. val optField : string -> 'a decoder -> ('a option -> 'b) decoder -> 'b decoder-
optField lab d kreturns a decoder for an optional object field that can be sequenced in a continuation-passing style. If the field is not present in the object, thenNONEis passed tok. val dfltField : string -> 'a decoder -> 'a -> ('a -> 'b) decoder -> 'b decoder-
dfltField lab d dflt kreturns a decoder for an optional object field that can be sequenced in a continuation-passing style. If the field is not present in the object, thendfltis passed tok. val array : 'a decoder -> 'a list decoder-
array dreturns a decoder that when applied to a JSON array, will decode the elements of the array using the decoderdand return the result as a list. It raises the exception valueJSONError(NotArray, jv)if the argumentjvis not a JSON array. val sub : int -> 'a decoder -> 'a decoder-
sub i dreturns a decoder that when given a JSON array, decodes thei'th element of the array using the decoderd. This decoder will raise the exception valueJSONError(NotArray, jv)if the argumentjvis not a JSON array, and the exception valueJSONError(ArrayBounds i, jv)if the indexiis out of bounds for the array. val at : JSONUtil.path -> 'a decoder -> 'a decoder-
at path dreturns a decoder that uses the path to select a value from its argument (seeJSONUtil.get) and then decodes that value using the decoderd. val succeed : 'a -> 'a decoder-
succeed vreturns a decoder that always yieldsvfor any argument. val fail : string -> 'a decoder-
fail msgreturns a decoder that raisesJSONError(Fail msg, jv)for any JSON inputjv. val andThen : ('a -> 'b decoder) -> 'a decoder -> 'b decoder-
andThen f dreturns a decoder that first usesdto decode a valuevfrom its argument and then returns the result of applyingftov. val orElse : 'a decoder * 'a decoder -> 'a decoder-
orElse (d1, d2)returns a decoder that tries to decode its argument using the decoder d1` and, if that fails, tries to decode the argument usingd2. val choose : 'a decoder list -> 'a decoder-
choose dsreturns a decoder that tries to decode its argument using each of the decoders in the listds, returning the first successful result. If all of the decoders fail, then the exception valueJSONError(Fail "no choice", jv)is raised, wherejvis the JSON value being decoded. The expressionchoose [d1, …, dn]is equivalent toorElse(d1, orElse(d2, ..., orElse(dn, fail "no choice") ... )) val map : ('a -> 'b) -> 'a decoder -> 'b decoder-
map f dreturns a decoder that applies the functionfto the result of decoding a JSON value using the decoderd. val map2 : ('a * 'b -> 'res) -> … -> 'res decoderval map3 : ('a * 'b * 'c -> 'res) -> … -> 'res decoderval map4 : ('a * 'b * 'c * 'd -> 'res) -> … -> 'res decoderval tuple2 : ('a decoder * 'b decoder) -> ('a * 'b) decoder-
tuple2 (d1, d2)is equivalent tomap2 Fn.id (d1, d2). val tuple3 : ('a decoder * 'b decoder * 'c decoder) -> ('a * 'b * 'c) decoder-
tuple3 (d1, d2, d3)is equivalent tomap2 Fn.id (d1, d2, d3). val tuple4 : ('a decoder * 'b decoder * 'c decoder * 'd decoder) -> ('a * 'b * 'c * 'd) decoder-
tuple4 (d1, d2, d3, d4)is equivalent tomap4 Fn.id (d1, d2, d3, d4). val delay : (unit -> 'a decoder) -> 'a decoder-
delay freturns a decoder that delays the application offto produce the decoder and can be used to define recursive decoders. The expressiondelay fis equivalent toandThen f (succeed ()).
Discussion
A number of these combinators work best when composed using a infix pipe operator.
For example:
fun |> (x, f) = f x
infix |>
val d = succeed (fn (n : string) => fn (a : int) => {name=n, age=a})
|> reqField "name" string
|> reqField "age" int