The JSONDecode structure

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 JSON null value.

exception NotBool of JSON.value

raised by the bool decode when the argument is not a JSON boolean. This exception is the same as JSONUtil.NotBool.

exception NotInt of JSON.value

raised by the int and intInf decoders when the argument is not a JSON integer number. This exception is the same as JSONUtil.NotInt.

exception NotNumber of JSON.value

raised by the number decoder when the argument is not a JSON number. This exception is the same as JSONUtil.NotNumber.

exception NotString of JSON.value

raised by the string decoder when the argument is not a JSON string. This exception is the same as JSONUtil.NotString.

exception NotObject of JSON.value

raised by the field decoder when the argument is not a JSON object. This exception is the same as JSONUtil.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 as JSONUtil.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 as JSONUtil.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 value exn. This function produces specialized messages for the exceptions defined in the JSONDecode 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 value jv using the decoder d. 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 string s.

val decodeFile : 'a decoder -> string -> 'a

decode d f decodes the JSON value that results from parsing the file f.

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 the Overflow exception if the integer is too large to be represented as an Int.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 JSON null value. When used to decode a null value, it will return its argument v; otherwise it will raise the NotNull 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 maps null to NONE and otherwise applies SOME to the result of decoding the value using the decoder d.

val try : 'a decoder -> 'a option decoder

try d returns a decoder that attempts to decode its argument using the decoder d. If it fails, then NONE 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 label lab using the decoder d. It will raise the NotObject exception when the argument is not a JSON object and the FieldNotFound 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 to seq (field lab d) k). It will raise the NotObject exception when the argument is not a JSON object and the FieldNotFound 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, then NONE is passed to k.

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, then dflt is passed to k.

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 decoder d and return the result as a list. It raises the NotArray 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 the i'th element of the array using the decoder d. This decoder will raise the NotArray exception if the argument is not a JSON array, and the ArrayBounds 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 (see JSONUtil.get) and then decodes that value using the decoder d.

val succeed : 'a -> 'a decoder

succeed v returns a decoder that always yields v for any argument.

val fail : string -> 'a decoder

fail msg returns a decoder that raises Failure(msg, jv) for any JSON input jv.

val andThen : ('a -> 'b decoder) -> 'a decoder -> 'b decoder

andThen f d returns a decoder that first uses d to decode a value v from its argument and then returns the result of applying f to v.

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 using d2.

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 list ds, returning the first successful result. If all of the decoders fail, the the Failure exception is raised. The expression choose [d1, …​, dn] is equivalent to

orElse(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 function f to the result of decoding a JSON value using the decoder d.

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 to map2 Fn.id (d1, d2).

val tuple3 : ('a decoder * 'b decoder * 'c decoder) -> ('a * 'b * 'c) decoder

tuple3 (d1, d2, d3) is equivalent to map2 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 to map4 Fn.id (d1, d2, d3, d4).

val delay : (unit -> 'a decoder) -> 'a decoder

delay f returns a decoder that delays the application of f to produce the decoder and can be used to define recursive decoders. The expression delay f is equivalent to andThen 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