I would like to combine lazy computation with reactive functional programming. In other words, I would like to be able to create a module with the following signature :

```
module Memoized_Reference : sig
type 'a t
val change_value : ('a t) -> 'a -> unit
val get_current_value : ('a t) -> 'a
val new_atomic : 'a -> ('a t)
val new_univariate_composite ('a->'b) -> ('a t) -> 'b
val new_bivariate_composite ('a1 -> 'a2 ->'b) -> ('a1 t) -> ('a2 t) -> 'b
val new_trivariate_composite ('a1 -> 'a2 -> 'a3 -> 'b) -> ('a1 t) -> ('a2 t) -> ('a3 t) -> 'b
end
```

and with the following proprerties :

- Every value of type
`t`

is either atomic or composite. - A value returned by
`new_atomic`

is always atomic, and a value returned by one of the several`_composite`

functions is always composite. - Atomic values behave like ordinary refs with respect to
`change_value`

and`get_current_value`

. -
`change_value`

raises an exception if called on a non-atomic (i.e. composite) value. - If a value
`y`

has been created as`new_bivariate_composite f x1 x2`

, then at any moment in time`get_current_value y`

will coincide with`f (get_current_value x1) (get_current_value x2)`

. Similarly for the other`_composite`

functions. - Computations are as lazy and deferred as possible.

In OCaml pseudo-code, type `t`

could be implemented as something like

```
type 'a t=
Atomic of 'a
|Uni_composite of ('b->'a)*('b t) for some 'b
|Bi_composite of ('b1->'b2->'a)*('b1 t)*('b2 t) for some 'b1,'b2
|Tri_composite of ('b1->'b2->'b3->'a)*('b1 t)*('b2 t)*('b3 t) for some 'b1,'b2,'b3
```

I have two questions :

- Is there a GADT trick to translate the above snippet into valid OCaml code ?
- What about the implementation of the whole module ? My guess is that it cannot be done directly in OCaml. If so, what would be the next best thing ?