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 Failure of string * JSON.value
exception NotBool of JSON.value
exception NotInt of JSON.value
exception NotNumber of JSON.value
exception NotString of JSON.value
exception NotObject of JSON.value
exception FieldNotFound of JSON.value * string
exception NotArray of JSON.value
exception ArrayBounds of JSON.value * 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 Failure of string * JSON.value
-
raised by the
fail
decoder. exception NotNull of JSON.value
-
raised by the
null
decoder when the argument is not the JSONnull
value. exception NotBool of JSON.value
-
raised by the
bool
decode when the argument is not a JSON boolean. This exception is the same asJSONUtil.NotBool
. exception NotInt of JSON.value
-
raised by the
int
andintInf
decoders when the argument is not a JSON integer number. This exception is the same asJSONUtil.NotInt
. exception NotNumber of JSON.value
-
raised by the
number
decoder when the argument is not a JSON number. This exception is the same asJSONUtil.NotNumber
. exception NotString of JSON.value
-
raised by the
string
decoder when the argument is not a JSON string. This exception is the same asJSONUtil.NotString
. exception NotObject of JSON.value
-
raised by the
field
decoder when the argument is not a JSON object. This exception is the same asJSONUtil.NotObject
. exception FieldNotFound of JSON.value * string
-
This exception is raised by the
field
decoder 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 raised by the
array
decoder when the argument is not a JSON array. This exception is the same asJSONUtil.NotArray
. exception ArrayBounds of JSON.value * int
-
This exception is raised when access to an array value is out of bounds. This exception is the same as
JSONUtil.ArrayBounds
. val exnMessage : exn -> string
-
exnMessage exn
returns an error-message string for the exception valueexn
. This function produces specialized messages for the exceptions defined in theJSONDecode
structure and 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 jv
decodes the JSON valuejv
using 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 s
decodes the JSON value that results from parsing the strings
. val decodeFile : 'a decoder -> string -> 'a
-
decode d f
decodes the JSON value that results from parsing the filef
. val bool : bool decoder
-
decodes a JSON Boolean value. This decoder raises the
NotBool
exception if the value is not a JSON Boolean. val int : int decoder
-
decodes a JSON integer value. This decoder raises the
NotInt
exception if the value is not a JSON integer and theOverflow
exception 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
NotInt
exception if the value is not a JSON integer. val number : Real64.real decoder
-
decodes a JSON number value. This decoder raises the
NotNumber
exception if the value is not a JSON number. val string : string decoder
-
decodes a JSON string value. This decoder raises the
NotString
exception if the value is not a JSON string. val null : 'a -> 'a decoder
-
null v
returns a decoder for the JSONnull
value. When used to decode anull
value, it will return its argumentv
; otherwise it will raise theNotNull
exception. 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 d
returns a decoder that mapsnull
toNONE
and otherwise appliesSOME
to the result of decoding the value using the decoderd
. val try : 'a decoder -> 'a option decoder
-
try d
returns a decoder that attempts to decode its argument using the decoderd
. If it fails, thenNONE
is returned. Otherwise,SOME
is applied to the result od decoding the value. val seq : 'a decoder → ('a -> 'b) decoder -> 'b decoder
-
seq d k
sequences decoding operations in a continuation-passing style. val field : string -> 'a decoder -> 'a decoder
-
field lab d
returns a decoder that decodes the object field with the labellab
using the decoderd
. It will raise theNotObject
exception when the argument is not a JSON object and theFieldNotFound
exception when the given object does not have a field with the specified label. val reqField : string -> 'a decoder -> ('a -> 'b) decoder -> 'b decoder
-
reqField lab d k
returns 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 theNotObject
exception when the argument is not a JSON object and theFieldNotFound
exception when the given object does not have a field with the specified label. val optField : string -> 'a decoder -> ('a option -> 'b) decoder -> 'b decoder
-
optField lab d k
returns 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, thenNONE
is passed tok
. val dfltField : string -> 'a decoder -> 'a -> ('a -> 'b) decoder -> 'b decoder
-
dfltField lab d dflt k
returns 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, thendflt
is passed tok
. val array : 'a decoder -> 'a list decoder
-
array d
returns a decoder that when applied to a JSON array, will decode the elements of the array using the decoderd
and return the result as a list. It raises theNotArray
exception if the argument is not a JSON array. val sub : int -> 'a decoder -> 'a decoder
-
sub i d
returns a decoder that when given a JSON array, decodes thei
'th element of the array using the decoderd
. This decoder will raise theNotArray
exception if the argument is not a JSON array, and theArrayBounds
exception if the index is out of bounds for the array. val at : JSONUtil.path -> 'a decoder -> 'a decoder
-
at path d
returns 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 v
returns a decoder that always yieldsv
for any argument. val fail : string -> 'a decoder
-
fail msg
returns a decoder that raisesFailure(msg, jv)
for any JSON inputjv
. val andThen : ('a -> 'b decoder) -> 'a decoder -> 'b decoder
-
andThen f d
returns a decoder that first usesd
to decode a valuev
from its argument and then returns the result of applyingf
tov
. 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 ds
returns 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, the theFailure
exception is raised. 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 d
returns a decoder that applies the functionf
to the result of decoding a JSON value using the decoderd
. val map2 : ('a * 'b -> 'res) -> … -> 'res decoder
val map3 : ('a * 'b * 'c -> 'res) -> … -> 'res decoder
val map4 : ('a * 'b * 'c * 'd -> 'res) -> … -> 'res decoder
val 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 f
returns a decoder that delays the application off
to produce the decoder and can be used to define recursive decoders. The expressiondelay f
is 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