Source file accessor_sexp.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
open! Base
open! Import
type t = Sexp.t =
| Atom of string
| List of t list
[@@deriving accessors]
let children = [%accessor list @> Accessor_list.each]
let tuple2 =
[%accessor
Accessor.variant
~match_:(function
| Sexp.List [ a; b ] -> First (a, b)
| (List _ | Atom _) as sexp -> Second sexp)
~construct:(fun (a, b) -> Sexp.List [ a; b ])]
;;
let field name =
children
@> tuple2
@> Accessor_tuple2.sndi
@> Accessor.filter_map_index (fun (n :: i) ->
if Sexp.equal (Atom name) n then Some i else None)
;;
let variant name = list @> Accessor_list.prefixed [ Atom name ] ~equal:Sexp.equal
let atoms =
let rec traverse =
let open Accessor.Many.Let_syntax in
function
| Atom atom ->
let%map atom = Accessor.Many.access atom in
Atom atom
| List sexps ->
let%map sexps = Accessor.Many.all (List.map sexps ~f:traverse) in
List sexps
in
[%accessor Accessor.many traverse]
;;
let conv (type a) (module A : Sexpable.S with type t = a) =
Accessor.variant
~match_:(fun sexp ->
match A.t_of_sexp sexp with
| a -> First a
| exception _ -> Second sexp)
~construct:A.sexp_of_t
;;
let conv_strict (type a) (module A : Sexpable.S with type t = a) =
Accessor.isomorphism ~get:A.t_of_sexp ~construct:A.sexp_of_t
;;