signal
Monadic builder syntax for Signals, inspired by those formerly used by arrow-kt.
signal introduces a scope allowing for the use of the SignalScope.bind method. This works similarly to Signal.value, but calls to bind within the block are recomputed whenever any of the Signals that bind was called on have updated values.
In effect then, signal gives us a nicer syntax for both Signal.flatMap as well as the various Signal.combineWiths, depending on how it is used.
For example, the following
foo.combineWith(bar) { foo, bar -> foo + bar }
is equivalent to:
state { foo.bind() + bar.bind() }
which is especially convenient for Signal.combineWith calls with many parameters.
For usages where the result of one Signal is bound and used in the rest of the block such as the following:
state {
val x = xState.bind()
val y = yState.bind()
if (x - y == 0) {
zState.bind()
} else {
wState.bind()
}
}
the result is equivalent to:
xState.flatMap { x ->
yState.flatMap { y ->
if (x - y == 0) {
zState
} else {
wState
}
}
}
In general, the signal builder lets you treat the bound results of a Signal as regular values, and have them automatically react to changes in input values the way you'd expect, but with a convenient sequential syntax -- letting you combine Signals in complex ways without having to deal with the large lambdas of Signal.combineWith or the nested callbacks needed for certain uses of Signal.flatMap.