This module contains functions for connecting FRP with the rest of the world. It contains low-level functions for creating futures, streams, and behaviors "from scratch". It also contains low-level functions consuming streams and behaviors by executing side-effects in response to their occurrences and value changes.

The module contains the following functions for creating reactive.

Since the functions in this module are low-level some of them necessitates the understanding a few details about how Hareactive is implemented. These are activation and deactivation of streams and behaviors and the difference between pull and push behaviors.

Activation and deactivation

When a stream or behavior is created in Hareactive it is inactive until other circumstanses forces it to activate. For instance, if s is a stream then map f s creates a new stream which is inactive. Since f is pure and since no one depends on the occurrences of the mapped stream the occurrences are actualy never computed.

As soon as something with an observable effect depends on the stream (like a stateful combinator such as accum or a function with side effects such as runStreamEffect) the stream will be activated. This is purely an optimization and it functions such that it does not leak into the rest of the API (as opposed to some other reactive libraries with similar notions that do escape into the API an affect every day users). However, when constructing streams and behaviors from scratch it is beneficial for performance reasons to understand activation/deactivation and create then such that they can activate and deactivate.

For instance, if creating a stream from DOM key press events then only when the stream is activated should it add and event listener to the DOM and when the stream is deactivated it should remove the event listener from the DOM.

Streams and behaviors that can activate and deactivate are created with the functions producerStream and producerBehavior respectively.

Push and pull behaviors

Behaviors in Hareactive can be in either a push state or a pull state. When a behavior is in the push state it will notify any listeners of any changes in its value. On the other hand, when a behavior is in the pull state any listeners must ask the behavior for changes whenever it is releant for them to do so. This distinction only affects the function observe which must handle behaviors in both states.

#Clock Source

data Clock :: Type

Hareactive represents time internally by using a logical clock. This type represents logical timestamps.

This type is opaque to users of Hareactive.

#ProducerFunction Source

type ProducerFunction a = (a -> Effect Unit) -> Effect (Effect Unit)

A ProducerFunction produces values by repeatedly invoking its first argument with new values.

#producerStream Source

#SinkFuture Source

data SinkFuture :: Type -> Type

#sinkFuture Source

sinkFuture :: forall a. Effect (SinkFuture a)

Creates a future that one can resolve imperatively by calling resolveFuture.

#sinkFuture' Source

sinkFuture' :: forall a. Effect { future :: Future a, sink :: SinkFuture a }

#resolveFuture Source

resolveFuture :: forall a. SinkFuture a -> a -> Effect Unit

#producerBehavior Source

producerBehavior :: forall a. ProducerFunction a -> (Clock -> Effect a) -> Behavior a

Create a behavior from a producer function.

#SinkStream Source

data SinkStream :: Type -> Type

#sinkStream Source

sinkStream :: forall a. Effect (SinkStream a)

An effectful computation that creates a SinkStream. A SinkStream is a sink that one can imperatively push occurrences into by using the pushSink function.

#sinkStream' Source

sinkStream' :: forall a. Effect { sink :: SinkStream a, stream :: Stream a }

This is a convenience function for the common use-case of calling sinkStream and then converting the SinkStream into a Stream with sinkStreamToStream.

The code

sink <- sinkStream
stream <- sinkStreamToStream sink

Is equivalent to

{ sink, stream } <- sinkStream'

#sinkStreamToStream Source

sinkStreamToStream :: SinkStream ~> Stream

Extract a Stream from a SinkStream. The resulting stream has an occurrence every time the SinkStream gets pushed into.

#pushSink Source

pushSink :: forall a. a -> SinkStream a -> Effect Unit

#subscribe Source

subscribe :: forall a. (a -> Effect Unit) -> Stream a -> Effect Unit

Executes the side-effect for each occurrence of the stream.

#observe Source

observe :: forall a. (a -> Effect Unit) -> (Effect Unit -> Effect (Effect Unit)) -> Behavior a -> Effect Unit

Executes side-effects in response to a behavior.