Apanatshka/elm-signal-extra/5.0.0

NOTE: this package is not compatible with Elm 0.19.1

Signal.Stream

Uninitialised signals, that only give updates and don't have the concept of a current value. Like Signal.Event.EventStream, only with values.

Streams of events. Many interactions with the world can be formulated as a stream of discrete events: mouse clicks, responses from servers, key presses, etc. This library provides the basic building blocks for routing these streams of events to your application logic.

Mapping

map : (a -> b) -> Stream a -> Stream b

Apply a function to events as they come in. This lets you transform streams.

type Action = MouseClick | TimeDelta Float


actions : Stream Action
actions =
    map (always MouseClick) Mouse.clicks

Merging

merge : Stream a -> Stream a -> Stream a

Merge two streams into one. This function is extremely useful for bringing together lots of different streams to feed into a fold.

type Action = MouseClick | TimeDelta Float


actions : Stream Action
actions =
    merge
        (map (always MouseClick) Mouse.clicks)
        (map TimeDelta (fps 40))

If an event comes from either of the incoming streams, it flows out the outgoing stream. If an event comes on both streams at the same time, the left event wins (i.e., the right event is discarded).

fairMerge : (a -> a -> a) -> Stream a -> Stream a -> Stream a

Like merge, but you get to decide which event wins when they come in at the same time.

mergeMany : List (Stream a) -> Stream a

Merge many streams into one. This is useful when you are merging more than two streams. When multiple events come in at the same time, the left-most event wins, just like with merge.

type Action = MouseMove (Int,Int) | TimeDelta Float | Click


actions : Stream Action
actions =
    mergeMany
        [ map MouseMove Mouse.position
        , map TimeDelta (fps 40)
        , map (always Click) Mouse.clicks
        ]

Folding

fold : (a -> b -> b) -> b -> Stream a -> Signal b

Create a past-dependent value. Each update from the incoming stream will be used to step the state forward. The outgoing signal represents the current state.

clickCount : Signal Int
clickCount =
    fold (\click total -> total + 1) 0 Mouse.clicks


timeSoFar : Stream Time
timeSoFar =
    fold (+) 0 (fps 40)

So clickCount updates on each mouse click, incrementing by one. timeSoFar is the time the program has been running, updated 40 times a second.

Filtering

filter : Stream (Maybe a) -> Stream a
filterMap : (a -> Maybe b) -> Stream a -> Stream b

Filter out some events. If the incoming event is mapped to a Nothing it is dropped. If it is mapped to Just a value, we keep the value.

numbers : Stream Int
numbers =
    filterMap (\raw -> Result.toMaybe (String.toInt raw)) userInput


userInput : Stream String
It seems that keepIf does not have any docs. The module's documentation names it in an @docs line, but the package does not expose it.
sample : (a -> b -> c) -> Signal a -> Stream b -> Stream c

Useful for augmenting a stream with information from a signal. For example, if you are operating on a time delta but want to take the current keyboard state into account.

inputs : Stream ({ x:Int, y:Int }, Time)
inputs =
    sample (,) Keyboard.arrows (fps 60)

Now we get events exactly with the (fps 60) stream, but they are augmented with which arrows are pressed at the moment.

Primitive Streams

never : Stream a

A stream that never gets an update. This is useful when defining functions like mergeMany which needs to be defined even when no streams are given.

mergeMany : List (Stream a) -> Stream a
mergeMany streams =
    List.foldr merge never streams
timestamp : Stream a -> Stream ( Time, a )

Add a timestamp to any stream. Timestamps increase monotonically. When you create (timestamp Mouse.x), an initial timestamp is produced. The timestamp updates whenever Mouse.x updates.

Timestamp updates are tied to individual events, so (timestamp Mouse.x) and (timestamp Mouse.y) will always have the same timestamp because they rely on the same underlying event (Mouse.position).

Conversions

toSignal : a -> Stream a -> Signal a

Apply a function to events as they come in. This lets you transform streams.

type Action = MouseClick | TimeDelta Float


actions : Stream Action
actions =
    map (always MouseClick) Mouse.clicks
fromSignal : Signal a -> Stream a

Get a stream that triggers whenever the signal is updated. Note that an update may result in the same value as before, so the resulting Stream can have the same value twice in a row.

moves : Stream (Int,Int)
moves =
  fromSignal Mouse.position