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
null
decoder when the argument is not the JSONnull
value. exception NotBool of JSON.value
-
used by the
bool
decode when the argument is not a JSON boolean. This exception is the same asJSONUtil.NotBool
. exception NotInt of JSON.value
-
used 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
-
used by the
number
decoder when the argument is not a JSON number. This exception is the same asJSONUtil.NotNumber
. exception NotString of JSON.value
-
used by the
string
decoder when the argument is not a JSON string. This exception is the same asJSONUtil.NotString
. exception NotObject of JSON.value
-
used 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 used 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 used 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 used 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 theJSONError
wrapped around the other exceptions defined in this structure (or theFail
exception). 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 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 exception value
JSONError(NotBool, jv)
if the valuejv
is not a JSON Boolean. val int : int decoder
-
decodes a JSON integer value. This decoder raises the exception value
JSONError(NotInt, jv)
if the argumentjv
is not a JSON integer value 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 exception value
JSONError(NotInt, jv)
if the argumentjv
is 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 valuejv
is not a JSON number. val string : string decoder
-
decodes a JSON string value. This decoder raises the exception value
JSONError(NotString, jv)
if the argumentjv
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 the exception valueJSONError(NotNull, jv)
when the argumentjv
is 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 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 the exception valueJSONError(NotObject, v)
when the argumentv
is not a JSON object and the exception valueJSONError(FieldNotFound lab, v)
, whenv
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 the exception valueJSONError(NotObject, v)
when the argumentv
is not a JSON object and the exception valueJSONError(FieldNotFound lab, v)
whenv
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 the exception valueJSONError(NotArray, jv)
if the argumentjv
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 the exception valueJSONError(NotArray, jv)
if the argumentjv
is not a JSON array, and the exception valueJSONError(ArrayBounds i, jv)
if the indexi
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 raisesJSONError(Fail 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, then the exception valueJSONError(Fail "no choice", jv)
is raised, wherejv
is 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 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