React is an OCaml package made for reactive programming using OCaml. The objective of this post is to illustrate and explain some examples of the React API. Therefore the basic concepts of React, such as Signals, Events and side effects, will not be repeated here. Below are some prerequisites for reading this post.
- OCaml (version 4.00.1 or above)
- OPAM (OCaml PAckage Manager)
- React (installation via OPAM)
- React Introduction
Most of the examples used in this post are inspired by test cases of React project. To report an issue in the post, contact me through my Github account. Thank you for your feedbacks.
Using React package
ocamlfind ocamlopt -o clock -linkpkg \ -package react clock.ml
For OCaml Toplevel
#use "topfind";; #require "react";; open React;;
once e is e with only its next occurence. Any occurence after time t will not affect e.
1 2 3 4 5 open React (* omitted in the examples below *) let w, send_w = E.create () let x = E.once w let pr_x = E.map print_int x let () = List.iter send_w [0; 1; 2; 3]
The output would be only 0. All the values after the first occurrence are omitted.
drop_once e is e without its next occurrence. Similarly, if we change the third line of the example above, the output would be 123. The reason is because the NEXT occurrence of e is omitted.
app ef e occurs when both ef and e occur simultaneously.
The output would be 246. As explained before, drop_once makes y only take updates from the second occurrence onwards. Variable z takes the value of x when both x and y are updated.
map f e applies f to e’s occurrences.
stamp e v is map (fun _ -> v) e. It fixes the occurrence of e to v.
filter p e are e’s occurrences that satisfy p.
fmap fm e are occurrences of e filtered and mapped by fm.
diff f e occurs whenever e occurs except on the next occurence. In another words, it is triggered since the second the occurrence. Occurences are f v v’ where v is e’s current occurrence and v’ the previous one.
changes eq e is the occurrences of e with occurences equal to the previous one dropped. Equality is tested with eq (defaults to structural equality). The behavior is similar to Signals.
The occurrences of y are 0310 (difference between current and previous one), while those of z are 034 (only changes are recorded).
dismiss c e is the occurences of e except the ones when c occurs.
The occurrences of y are 246 (even numbers). Occurrences of z are 135. When y has occurrence, z will not have any occurrence.
until c e is e’s occurences until c occurs.
The output is ab. All the occurrences after stop event are dropped, although stop has no more new updates.
accum ef i accumulates a value, starting with i, using e’s functional occurrences. It takes the previous occurrence, applies to the function and evaluates the result as the current occurrence.
fold f i e accumulates the occurrences of e with f starting with i. The behavior of fold is similar to List.fold_left.
The output would be 1 2 6 24.
select el is the occurrences of every event in el. If more than one event occurs simultaneously the leftmost is taken and the others are lost.
The expected occurrences of all variables are written in the comments. To know more about simultaneous events, read this.
merge f a el merges the simultaneous occurrences of every event in el using f and the accumulator a. You may refer to the previous API to check the meaning of simultaneous events.
The occurrences of z are [2; 1], , [3; 2]. Hint: fun acc v -> v::acc pushes every v to the accumulator acc.
switch e ee is e’s occurrences until there is an occurrence e’ on ee, the occurrences of e’ are then used until there is a new occurrence on ee, etc.
fix ef allows to refer to the value an event had an infinitesimal amount of time before.
hold i e has the value of e’s last occurrence or i if there was not any.
1 2 3 4 let x, send_x = E.create () let a = S.hold 0 x let pr_a = S.map print_int a List.iter send_x [1; 2; 3; 3; 3; 4; 4; 4]
A 0 will printed out at line 3 because x has no occurrences by then. Then 1234 will be printed. Note that only updates that change the value of a signal are printed.
Many API are similar to those in React.E. Therefore this tutorial jumps straight to Lifting combinators. Lifting transforms a regular function to make it act on signals. For example, l2 takes a function with two arguments as its input.