In Elm, when the value under the signal is of a composite type like a list, how to efficiently update one element

I'm new to Elm and am very attracted to the way Elm is doing GUI. But after some deep thought, I find it difficult to effectively update only one element of the list or finger tree (just like the finger tree in Haskell if it already exists in the Elm library) that is under the signal, and its size also varies against time.

In particular, to express a dynamic finger tree, we must write

Signal [{- type of element of the finger tree-}]

But if we want to efficiently update only one element of the finger tree, we must write

Signal [Signal {- basic data type -}]

But in Elm Signal is not a Monad, then how to smooth two layers of Signals into one layer?

Comment 1: I do not know in detail how Elm behaves in this situation. Re-processing the whole finger is just my guess.

Comment 2: For example, suppose we have a signal value marked as s

, type Signal (fingerTree Int)

, and the next function, marked as f

, whose input s

is, for example, lift (fmap (+1))

whose type Signal (fingerTree Int) -> Signal (fingerTree Int)

. And if s

it only has one element, the function f

must re-execute the operation (+1) for each element s

. Obviously, this is a waste of time and I'm not sure if Elm is enough to detect immutability.

+3


source to share


1 answer


TL; DR: execute your logic / data processing as pure functions and lift them up to convert signals.

The trick is to write a function processList : [elementType] -> [elementType]

that provides the required logic (check if the third element is a vibbler and change it to wobbler or what you want to do) and then use the elevator function which is Type

lift : (a -> b) -> Signal a -> Signal b

      

how lift processList mySignalThatProducesLists

to edit the data received with mySignalThatProducesLists

, with processList

.



The basic idea here is that you code your logic and data processing as pure functions and then use them as signal transformers using lift

. It, like Elm, automatically repeats the function every time the data in the original signal is updated.

If you are used to programming in Haskell, you can think of Signal a

how to wrap a newtype around Time -> a

for some opaque time type and lift

how fmap

. You don't need to have a monad to edit data.

There are also functions lift2

and lift3

lifting functions with more than one argument, so again, to use the analogy with Haskell, you essentially have the possibility of applicative functor.

The reason they don't have Monad is because it imposes implementation details that reduce efficiency. Maybe there is some ArrowApply equivalent in there that I didn't notice (that would give you confidence in the Monad expression), but I'm not sure which is.

+5


source







All Articles