Page
Library
Module
Module type
Parameter
Class
Class type
Source
Sexp_decodeSourceA library of monadic combinators for decoding S-expressions (as defined in the Csexp library) into structured data.
Copyright © Inria 2022
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]
return v is the constant decoder: it always returns the value v. It does not consume any part of the input.
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.
let+ x = d in t is the same as map (fun x -> t) d
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.
skip_all accepts everything until no element is available anymore. Consomes 0 or more elements.
no_more returns () when there is no more S-expression available. Consumones nothing.
bool accepts Atom "true" by returning true, and accepts Atom "false" by returning false. Consumes one element.
int accepts Atom s by returning the integer n denoted by the string s. Consumes one element.
int accepts Atom s by returning the float f denoted by the string s. Consumes one element.
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.
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 decoderSame 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 decoderfields_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.
tuple2 d1 d2 is the same as pair d1 d2
Similar to tuple2, but decodes tuples of length 3
val tuple4 :
'a decoder ->
'b decoder ->
'c decoder ->
'd decoder ->
('a * 'b * 'c * 'd) decoderSimilar 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) decoderSimilar 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) decoderSimilar 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) decoderSimilar 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) decoderSimilar 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.