package bonsai

  1. Overview
  2. Docs
Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source

Source file bonsai.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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
open! Core_kernel
open! Import
include Bonsai_intf

module Generic = struct
  include Component
  include Packed

  let eval = eval_ext

  let sexp_of_t (T { unpacked; action_type_id = _; model = _ }) =
    sexp_of_unpacked unpacked
  ;;

  (* Constructor Functions *)

  let const = Const.const
  let pure = Pure.pure
  let leaf = Leaf.leaf

  module type Enum = Switch.Enum

  let enum = Switch.enum
  let if_ = Switch.if_

  (* Modifier Functions *)
  let compose = Compose.compose
  let map = Mapn.map
  let map2 = Mapn.map2
  let map_input = Map_input.map_input
  let return = const
  let both = Mapn.both
  let ( >>| ) t f = map t ~f

  module Infix = struct
    let ( >>> ) = compose
    let ( >>| ) = ( >>| )
    let ( @>> ) f t = map_input t ~f
  end

  module Proc = Proc
  open Infix

  let state_machine = Leaf.state_machine
  let input = Pure.input

  module List_deprecated = struct end

  module With_incr = struct
    let pure = Pure_incr.pure_incr
    let of_incr t = pure ~f:(Fn.const t)
    let leaf = Leaf_incr.leaf_incr
    let model_cutoff = Cutoff.model_cutoff
    let value_cutoff = Cutoff.value_cutoff
    let map = Map_incr.map_incr
    let map_input t ~f = compose (pure ~f) t
  end

  module Map = struct
    module type Comparator = Bonsai_types.Comparator

    type ('k, 'cmp) comparator = ('k, 'cmp) Bonsai_types.comparator

    let associ_input_with_extra = Assoc.associ_input

    let associ_input comparator t =
      (fun map -> map, ())
      @>> associ_input_with_extra comparator ((fun (k, i, _) -> k, i) @>> t)
    ;;

    let assoc_input comparator t =
      (fun map -> map, ())
      @>> associ_input_with_extra comparator ((fun (_, i, _) -> i) @>> t)
    ;;

    let merge a b ~f =
      both a b
      |> With_incr.map ~f:(fun pair ->
        let open Incremental.Let_syntax in
        let return = pair |> Incremental.state |> Incremental.return in
        let%pattern_bind a, b = pair in
        Incr_map.merge a b ~f)
    ;;
  end

  module Open_on_rhs_intf = struct
    module type S = sig end
  end

  module Let_syntax = struct
    let return = return
    let map = map
    let both = both

    include Infix

    module Let_syntax = struct
      let return = return
      let both = both
      let map = map
      let sub = Proc.sub

      module Open_on_rhs = Infix
    end
  end

  module Arrow = struct
    let arr f = pure ~f
    let first t = both (fst @>> t) (arr snd)
    let second t = both (arr fst) (snd @>> t)
    let split t u = both (fst @>> t) (snd @>> u)
    let fanout = both
    let extend_first component = pure ~f:(fun x -> x, x) >>> first component
    let extend_second component = pure ~f:(fun x -> x, x) >>> second component
    let ( *** ) = split
    let ( &&& ) = fanout
    let ( ^>> ) = ( @>> )
    let ( >>^ ) = ( >>| )

    let partial_compose_first a b =
      let rearrange ((shared, output1), input) = output1, (input, shared) in
      extend_first a >>> rearrange @>> second b
    ;;

    let pipe from ~into ~via ~finalize =
      let intermediate =
        let%map i, r1 = extend_second from in
        (i, r1), via i r1
      in
      let%map (i, r), r2 = intermediate >>> second into in
      finalize i r r2
    ;;
  end

  module Expert = struct
    module Snapshot = Snapshot

    type nonrec ('input, 'model, 'action, 'result, 'incr, 'event) unpacked =
      ('input, 'model, 'action, 'result, 'incr, 'event) unpacked

    include Packed

    let reveal = Fn.id
    let conceal = Fn.id
    let of_full = Full.of_full
    let eval = eval
    let optimize = Optimize.optimize
  end
end

module type S = sig
  module Incr : Incremental.S
  module Event : Event.S

  include
    S_gen
    with module Incr := Incr
    with module Event := Event
    with type 'a Proc.Computation.t =
           ('a, Incr.state_witness, Event.t) Generic.Proc.Computation.t

  val to_generic : ('i, 'r) t -> ('i, 'r, Incr.state_witness, Event.t) Generic.t
  val of_generic : ('i, 'r, Incr.state_witness, Event.t) Generic.t -> ('i, 'r) t
end

module Make (Incr : Incremental.S) (Event : Event.S) :
  S with module Incr = Incr and module Event = Event = struct
  module Incr = Incr
  module Event = Event
  include Generic

  type ('i, 'r) t = ('i, 'r, Incr.state_witness, Event.t) Generic.Packed.t

  module Proc = struct
    include Generic.Proc

    module Computation = struct
      type 'a t = ('a, Incr.state_witness, Event.t) Proc.Computation.t
    end
  end

  let to_generic = Fn.id
  let of_generic = Fn.id

  module type S = sig
    module Input : T
    module Model : Model
    module Action : Action
    module Result : T

    val apply_action
      :  inject:(Action.t -> Event.t)
      -> schedule_event:(Event.t -> unit)
      -> Input.t
      -> Model.t
      -> Action.t
      -> Model.t

    val compute : inject:(Action.t -> Event.t) -> Input.t -> Model.t -> Result.t
    val name : string
  end

  type ('input, 'model, 'action, 'result) component_s =
    (module S
      with type Input.t = 'input
       and type Model.t = 'model
       and type Action.t = 'action
       and type Result.t = 'result)

  module M (Component : S) = struct
    type nonrec t = (Component.Input.t, Component.Result.t) t
  end

  let of_module (type i m a r) m ~default_model =
    let module M = (val m : S
                    with type Input.t = i
                     and type Action.t = a
                     and type Model.t = m
                     and type Result.t = r)
    in
    leaf
      (module M.Model)
      (module M.Action)
      ~name:M.name
      ~default_model
      ~apply_action:M.apply_action
      ~compute:M.compute
  ;;

  include struct
    open Applicative.Make2_using_map2 (struct
        type nonrec ('r, 'i) t = ('i, 'r) t

        let map = `Custom map
        let map2 = map2
        let return = const
      end)

    module Applicative_infix = Applicative_infix

    let all = all
    let all_unit = all_unit
    let apply = apply
    let both = both
    let map3 = map3
    let return = return
    let ( <* ) = ( <* )
    let ( *> ) = ( *> )
    let ( <*> ) = ( <*> )
    let ( >>| ) = ( >>| )
  end

  module With_incr = struct
    include With_incr

    module type S = sig
      module Input : T
      module Model : Model
      module Action : Action
      module Result : T

      val apply_action
        :  Input.t Incr.t
        -> Model.t Incr.t
        -> inject:(Action.t -> Event.t)
        -> (schedule_event:(Event.t -> unit) -> Action.t -> Model.t) Incr.t

      val compute
        :  Input.t Incr.t
        -> Model.t Incr.t
        -> inject:(Action.t -> Event.t)
        -> Result.t Incr.t

      val name : string
    end

    type ('input, 'model, 'action, 'result) component_s =
      (module S
        with type Input.t = 'input
         and type Model.t = 'model
         and type Action.t = 'action
         and type Result.t = 'result)

    let of_module (type i m a r) m =
      let module M = (val m : S
                      with type Input.t = i
                       and type Action.t = a
                       and type Model.t = m
                       and type Result.t = r)
      in
      Leaf_incr.leaf_incr
        (module M.Model)
        (module M.Action)
        ~name:M.name
        ~apply_action:M.apply_action
        ~compute:M.compute
    ;;
  end
end

module Snapshot = Snapshot