Library
Module
Module type
Parameter
Class
Class type
A library of monadic combinators for decoding S-expressions (as defined in the Csexp
library) into structured data.
The type of S-expressions, as defined by the Csexp
library
Type of decoders: a decoder of type 'a decoder
decodes a list of S-expressions into a value of type 'a
. A decoder contains a state of which S-expression is next available, and which ones should be processed later.
run_list d l
tries to decode the list of S-expression l
into a structure value, using the decoder d
run d s
tries to decode the S-expression s
into a structure value, using the decoder d
. This is the same as run_list d [s]
val return : 'a -> 'a decoder
return v
is the constant decoder: it always returns the value v
. It does not consume any part of the input.
val const : 'a -> 'a decoder
const v
is the same as return v
val error : 'a decoder
error
is the decoder that always fails
fail_default v d
fails when d
succeeds, and succeeds by returning v
when d
fails
map f d
succeeds and returns f x
when d
succeeds and returns x
. When d
fails, map f d
fails as well.
Monadic bind: bind d f
first decodes using d
, and if d
succeeds with a value v
, then decoding is performed using f v
.
let* x = d in t
is the same as bind d (fun x -> t)
seq d1 d2
is the decoder that first decodes with d1
, drops its result, and decodes using d2
. Fails when d1
fails, and when d1
succeeds and d2
fails.
Same as seq d1 d2
, but keeps the result of d1
and drops the result of d2
or_else d1 d2
first decodes with d1
, and stops there if d1
succeeds. If d1
fails, then decoding with d2
is performed.
first [d1; ... ; dn]
selects the first decoder di
that succeeds
or_else_delayed d1 (fun () -> d2)
behaves the same as or_else
d1 d2
, with the difference that the evaluation of the second operand is delayed. This is useful when defining recursive decoders, when d2
refers to a recursive calls.
d |+>> f
is the same as or_else_delayed d f
raw
accepts Atom s
and List l
, and returns that S-expression. Consumes one element.
val skip : unit decoder
skip
accepts Atom s
and List l
, and returns ()
. Consumes one element.
val skip_all : unit decoder
skip_all
accepts everything until no element is available anymore. Consomes 0 or more elements.
val atom : string decoder
atom
accepts Atom s
, and returns s
. Consumes one element.
val no_more : unit decoder
no_more
returns ()
when there is no more S-expression available. Consumones nothing.
val bool : bool decoder
bool
accepts Atom "true"
by returning true
, and accepts Atom "false"
by returning false
. Consumes one element.
val int : int decoder
int
accepts Atom s
by returning the integer n
denoted by the string s
. Consumes one element.
val float : float decoder
int
accepts Atom s
by returning the float f
denoted by the string s
. Consumes one element.
val string : ?escaped:bool -> string decoder
string ~escaped
accepts Atom s
and returns s
when escaped=false
, or the unescaped interpretation of s
when escaped=true
. Default: escaped=false
. Consumes one element.
val tag : string -> string decoder
tag name
accepts Atom s
when s = name
, and returns s
. Consumes one element.
peek d
returns Some v
if d
succeeds with v
, or returns None
otherwise, and restores the state as it was before calling d
. Consumes nothing.
group d
accepts List l
when d
accepts l
, and returns the result provided by d
. Consumes one element.
field name d
recognizes List [Atom s; e1; ... ; en]
where s = name
and d
recognizes [e1; ...; en]
. Consumes one element.
variant cases
accepts List [Atom name; e1; ...; en]
such that (name, d)
is found in the association list cases
, and d
accepts [e1; ...; en]
. Only the first match for name
is tried: the other ones are ignored.
record ~default [(name1, d1); ...; (namen, dn)]
recognizes List [List (Atom name'1 :: l'1); ...; List (Atom name'k :: l'k)]
where for every name'i
, there exists j
such that name'i = namej
, and l'i
is accepted by dj
. In case of success, the output value is fjn ( ... (fj1 default) ...)
where the fjk
are the values produced by djk
.
The record
combinator is useful to define decoders for records, in which fields may be given in any order. For every field, each decoder in the list produces a function that updates the corresponding field of the record. Each field entry is processed in the order in which they appear. Each field is optional.
Example:
# type t = { fst: int; snd: bool };;
type t = { fst : int; snd : bool; }
# let d =
record ~default:{ fst = 0; snd = false }
[ "fst", (let+ i = int in fun t -> { t with fst = i })
; "snd", (let+ b = bool in fun t -> { t with snd = b })
];;
val d: t decoder = <abstr>
The decoder d
will produce the following results:
# run d (List [List [Atom "fst"; Atom "42"]; List [Atom "snd"; Atom "true"]])
- : t option = Some {fst = 42; snd = true}
# run d (List [List [Atom "snd"; Atom "false"]; List [Atom "fst"; Atom "42"]]);;
- : t option = Some {fst = 42; snd = false}
# run d (List [List [Atom "snd"; Atom "true"]]);;
- : t option = Some {fst = 0; snd = true}
# run d (List [List [Atom "fst"; Atom "42"]]);;
- : t option = Some {fst = 42; snd = false}
# run d (List [List [Atom "fst"; Atom "42"]; List [Atom "fst"; Atom "43"]]);;
- : t option = Some {fst = 43; snd = false}
fields
has the same behaviour as record
, with the difference that the enclosing List [...]
is not expected. In other words, record ~default fs = group (fields ~default fs)
.
val record_advanced :
default:'a ->
(string * [< `Required | `Unique ] list * ('a -> 'a) decoder) list ->
'a decoder
Same as record
, but with the ability to specify whether fields are mandatory (i.e., they must appear at least once), or whether they are unique (i.e., they must appear at most once). Fields with an empty list of options may appear 0, 1 or more times.
val fields_advanced :
default:'a ->
(string * [< `Required | `Unique ] list * ('a -> 'a) decoder) list ->
'a decoder
fields_advanced
has the same behaviour as record_advanced
, with the difference that the enclosing List [...]
is not expected. In other words, record_advanced ~default fs = group (fields_advanced ~default fs)
.
pair d1 d2
decodes a pair: it first decodes using d1
, then using d2
if d1
succeeds. The decoded result is (v1, v2)
, where v1
is returned by d1
and v2
is return by d2
.
Similar to tuple2
, but decodes tuples of length 3
Similar to tuple2
, but decodes tuples of length 4
val tuple5 :
'a decoder ->
'b decoder ->
'c decoder ->
'd decoder ->
'e decoder ->
('a * 'b * 'c * 'd * 'e) decoder
Similar to tuple2
, but decodes tuples of length 5
val tuple6 :
'a decoder ->
'b decoder ->
'c decoder ->
'd decoder ->
'e decoder ->
'f decoder ->
('a * 'b * 'c * 'd * 'e * 'f) decoder
Similar to tuple2
, but decodes tuples of length 6
val tuple7 :
'a decoder ->
'b decoder ->
'c decoder ->
'd decoder ->
'e decoder ->
'f decoder ->
'g decoder ->
('a * 'b * 'c * 'd * 'e * 'f * 'g) decoder
Similar to tuple2
, but decodes tuples of length 7
val tuple8 :
'a decoder ->
'b decoder ->
'c decoder ->
'd decoder ->
'e decoder ->
'f decoder ->
'g decoder ->
'h decoder ->
('a * 'b * 'c * 'd * 'e * 'f * 'g * 'h) decoder
Similar to tuple2
, but decodes tuples of length 8
Decoder for the standard representation of options as S-expressions.
option d
decodes List []
into None
, and List [e]
into Some v
where the decoder d
decodes e
into v
.
Decoder for the standard representation of lists as S-expressions.
list d
decodes List [e1; ...; en]
into the list [v1; ...; vn]
where the decoder d
decodes every element ei
into a value vi
.
maybe d
produces Some v
if d
produces a value v
, and None
if d
fails
maybe_with_default default d
produces v
if d
produces a value v
, and returns the value default
if d
fails
repeat_list ~until d
recognizes e1; ...; en; f
such that until
recognizes f
and such that d
recognizes each ei
. If di
produces vi
, then repeat_list ~until d
produces the list v1; ... ; vn
. d
can succeed 0 or more times.
repeat1_list ~until d
is similar to repeat_list ~until d
, but forces that d
succeeds at least once
repeat_full_list d
is the same as repeat_list ~until:no_more d
repeat1_full_list d
is the same as repeat1_list ~until:no_more d
repeat ~until d
is similar to repeat_list ~until d
, but returns ()
instead of a list
repeat1 ~until d
is similar to repeat1_list ~until d
, but returns ()
instead of a list
repeat_fold_left ~until ~init d
recognizes e1; ...; en; f
such that until
recognizes f
and such that d
recognizes each ei
. If di
produces fi
, then repeat_list ~until d
produces the result of the expression fn (... (f1 init) ...)
. d
can succeed 0 or more times.
repeat_fold_right ~until ~init d
recognizes e1; ...; en; f
such that until
recognizes f
and such that d
recognizes each ei
. If di
produces fi
, then repeat_list ~until d
produces the result of the expression f1 (... (fn init) ...)
. d
can succeed 0 or more times.
filter p d
succeeds and returns v
when d
returns v
and p
v = true
. Otherwise, filter p d
fails.