Observable Sharing
Observable sharing is a technique used in reactive-banana to ensure that when you use a host language binding (like Haskell's let) to define an FRP primitive, the underlying computation is shared rather than duplicated.
Without observable sharing, a definition like let e = filterE p event in (e, e) might result in the filter logic being executed twice. With observable sharing, the library detects that the same variable is being used and ensures the underlying Pulse or Latch is only constructed once.
The Caching Mechanism
In the implementation, this is achieved via the Cached type from Reactive.Banana.Prim.High.Cached.
Cached m a: Describes an action of type m a that is designed to be executed only once. Subsequent attempts to execute the same cached action will simply retrieve the previously computed result.cache :: m a -> Cached m a: This function wraps an arbitrary action m a in a caching mechanism. It uses internal side effects (similar to unsafePerformIO and mutable references) to ensure the action's result is stored and reused.
In reactive-banana, Events and Behavior are defined as Cached actions within the Moment monad:
type Behavior a = Cached Moment (Latch a, Pulse ())
type Events a = Cached Moment (Pulse a)