2013-03-11 02:03:42 +00:00
|
|
|
|
2013-03-24 12:45:56 +00:00
|
|
|
-- The library for general signal manipulation. Some useful functions for
|
|
|
|
-- working with time (e.g. setting FPS) and combining signals and time (e.g.
|
|
|
|
-- delaying updates, getting timestamps) can be found in the
|
|
|
|
-- [`Time`](/docs/Signal/Time.elm) library.
|
2013-05-11 20:44:28 +00:00
|
|
|
--
|
2013-03-24 12:45:56 +00:00
|
|
|
-- Note: There are lift functions up to `lift8`.
|
2013-03-11 02:03:42 +00:00
|
|
|
module Signal where
|
|
|
|
|
2013-04-03 16:54:10 +00:00
|
|
|
import Native.Signal as S
|
|
|
|
import List as L
|
2013-03-11 02:03:42 +00:00
|
|
|
|
2013-03-24 12:45:56 +00:00
|
|
|
-- Create a constant signal that never changes.
|
2013-03-11 02:03:42 +00:00
|
|
|
constant : a -> Signal a
|
|
|
|
|
2013-03-24 12:45:56 +00:00
|
|
|
-- Transform a signal with a given function.
|
2013-03-11 02:03:42 +00:00
|
|
|
lift : (a -> b) -> Signal a -> Signal b
|
2013-03-24 12:45:56 +00:00
|
|
|
|
|
|
|
-- Combine two signals with a given function.
|
2013-03-11 02:03:42 +00:00
|
|
|
lift2 : (a -> b -> c) -> Signal a -> Signal b -> Signal c
|
2013-03-24 12:45:56 +00:00
|
|
|
|
|
|
|
-- Combine three signals with a given function.
|
2013-03-11 02:03:42 +00:00
|
|
|
lift3 : (a -> b -> c -> d) -> Signal a -> Signal b -> Signal c -> Signal d
|
|
|
|
lift4 : (a -> b -> c -> d -> e) -> Signal a -> Signal b -> Signal c -> Signal d -> Signal e
|
|
|
|
lift5 : (a -> b -> c -> d -> e -> f) -> Signal a -> Signal b -> Signal c -> Signal d -> Signal e -> Signal f
|
2013-05-16 20:10:50 +00:00
|
|
|
lift6 : (a -> b -> c -> d -> e -> f -> g)
|
|
|
|
-> Signal a -> Signal b -> Signal c -> Signal d -> Signal e -> Signal f -> Signal g
|
|
|
|
lift7 : (a -> b -> c -> d -> e -> f -> g -> h)
|
|
|
|
-> Signal a -> Signal b -> Signal c -> Signal d -> Signal e -> Signal f -> Signal g -> Signal h
|
|
|
|
lift8 : (a -> b -> c -> d -> e -> f -> g -> h -> i)
|
|
|
|
-> Signal a -> Signal b -> Signal c -> Signal d -> Signal e -> Signal f -> Signal g -> Signal h -> Signal i
|
2013-03-11 02:03:42 +00:00
|
|
|
|
2013-03-24 12:45:56 +00:00
|
|
|
-- Create a past-dependent signal. Each value given on the input signal will
|
|
|
|
-- be accumulated, producing a new output value.
|
2013-05-11 20:44:28 +00:00
|
|
|
--
|
2013-03-24 12:45:56 +00:00
|
|
|
-- For instance, `(foldp (\\t acc -> acc + 1) 0 (Time.every second))` increments every second.
|
2013-03-11 02:03:42 +00:00
|
|
|
foldp : (a -> b -> b) -> b -> Signal a -> Signal b
|
|
|
|
|
2013-03-24 12:45:56 +00:00
|
|
|
-- Merge two signals into one, biased towards the first signal if both signals
|
|
|
|
-- update at the same time.
|
2013-03-11 02:03:42 +00:00
|
|
|
merge : Signal a -> Signal a -> Signal a
|
2013-03-24 12:45:56 +00:00
|
|
|
|
|
|
|
-- Merge many signals into one, biased towards the left-most signal if multiple
|
|
|
|
-- signals update simultaneously.
|
2013-03-11 02:03:42 +00:00
|
|
|
merges : [Signal a] -> Signal a
|
2013-03-24 12:45:56 +00:00
|
|
|
|
2013-05-16 20:10:50 +00:00
|
|
|
-- Combine a list of signals into a signal of lists.
|
2013-04-03 16:54:10 +00:00
|
|
|
combine : [Signal a] -> Signal [a]
|
2013-04-03 17:35:18 +00:00
|
|
|
combine = L.foldr (S.lift2 (::)) (S.constant [])
|
2013-04-03 16:54:10 +00:00
|
|
|
|
2013-05-16 20:10:50 +00:00
|
|
|
-- Merge two signals into one, but distinguishing the values by marking the first
|
|
|
|
-- signal as `Left` and the second signal as `Right`. This allows you to easily
|
|
|
|
-- fold over non-homogeneous inputs.
|
|
|
|
-- mergeEither : Signal a -> Signal b -> Signal (Either a b)
|
2013-03-11 02:03:42 +00:00
|
|
|
|
2013-03-24 12:45:56 +00:00
|
|
|
-- Count the number of events that have occured.
|
2013-03-11 02:03:42 +00:00
|
|
|
count : Signal a -> Signal Int
|
2013-03-24 12:45:56 +00:00
|
|
|
|
|
|
|
-- Count the number of events that have occured that satisfy a given predicate.
|
2013-03-11 02:03:42 +00:00
|
|
|
countIf : (a -> Bool) -> Signal a -> Signal Int
|
|
|
|
|
2013-03-24 12:45:56 +00:00
|
|
|
-- Keep only events that satisfy the given predicate. Elm does not allow
|
|
|
|
-- undefined signals, so a base case must be provided in case the predicate is
|
|
|
|
-- never satisfied.
|
2013-03-11 02:03:42 +00:00
|
|
|
keepIf : (a -> Bool) -> a -> Signal a -> Signal a
|
2013-03-24 12:45:56 +00:00
|
|
|
|
|
|
|
-- Drop events that satisfy the given predicate. Elm does not allow undefined
|
|
|
|
-- signals, so a base case must be provided in case the predicate is never
|
|
|
|
-- satisfied.
|
2013-03-11 02:03:42 +00:00
|
|
|
dropIf : (a -> Bool) -> a -> Signal a -> Signal a
|
2013-03-24 12:45:56 +00:00
|
|
|
|
|
|
|
-- Keep events only when the first signal is true. When the first signal becomes
|
|
|
|
-- true, the most recent value of the second signal will be propagated. Until
|
|
|
|
-- the first signal becomes false again, all events will be propagated. Elm does
|
|
|
|
-- not allow undefined signals, so a base case must be provided in case the first
|
|
|
|
-- signal is never true.
|
2013-03-11 02:03:42 +00:00
|
|
|
keepWhen : Signal Bool -> a -> Signal a -> Signal a
|
2013-03-24 12:45:56 +00:00
|
|
|
|
|
|
|
-- Drop events when the first signal is true. When the first signal becomes false,
|
|
|
|
-- the most recent value of the second signal will be propagated. Until the first
|
|
|
|
-- signal becomes true again, all events will be propagated. Elm does not allow
|
|
|
|
-- undefined signals, so a base case must be provided in case the first signal is
|
|
|
|
-- always true.
|
2013-03-11 02:03:42 +00:00
|
|
|
dropWhen : Signal Bool -> a -> Signal a -> Signal a
|
2013-03-24 12:45:56 +00:00
|
|
|
|
|
|
|
-- Drop sequential repeated values. For example, if a signal produces the
|
|
|
|
-- sequence `[1,1,2,2,1]`, it becomes `[1,2,1]` by dropping the values that
|
|
|
|
-- are the same as the previous value.
|
2013-03-11 02:03:42 +00:00
|
|
|
dropRepeats : Signal a -> Signal a
|
|
|
|
|
2013-03-24 12:45:56 +00:00
|
|
|
-- Sample from the second input every time an event occurs on the first input.
|
|
|
|
-- For example, `(sampleOn clicks (every second))` will give the approximate
|
|
|
|
-- time of the latest click.
|
2013-03-11 02:03:42 +00:00
|
|
|
sampleOn : Signal a -> Signal b -> Signal b
|
|
|
|
|
2013-04-03 16:54:10 +00:00
|
|
|
-- An alias for `lift`. A prettier way to apply a
|
|
|
|
-- function to the current value of a signal.
|
2013-05-17 20:46:08 +00:00
|
|
|
--
|
|
|
|
-- lift f signal == f <~ signal
|
2013-04-03 16:54:10 +00:00
|
|
|
(<~) : (a -> b) -> Signal a -> Signal b
|
|
|
|
|
|
|
|
-- Signal application. This takes two signals, holding a function and
|
|
|
|
-- a value. It applies the current function to the current value.
|
2013-05-11 20:44:28 +00:00
|
|
|
--
|
2013-04-03 16:54:10 +00:00
|
|
|
-- So the following expressions are equivalent:
|
2013-05-11 20:44:28 +00:00
|
|
|
--
|
2013-05-17 20:46:08 +00:00
|
|
|
-- scene <~ Window.dimensions ~ Mouse.position
|
|
|
|
-- lift2 scene Window.dimensions Mouse.position
|
2013-04-03 16:54:10 +00:00
|
|
|
(~) : Signal (a -> b) -> Signal a -> Signal b
|