haskellfrpreactive-banana

Resettable accumulator behaviors?


I'm trying to wrap my head around FRP and I'm not sure that I'm doing it right. I want to build up a string from key press events up until enter is pressed. Once enter is pressed, the string gets written out and the accumulator is reset to the empty string.

I have a event source that emits a Char every time a key on the keyboard is pressed, ePressed. First, I separate out the two kinds of key presses I care about:

eWritable = filterE (`elem` ['A'..'z']) ePressed
eEnter = filterE (== '\n') ePressed

Now I know how to gather them together into what I want to send out:

eToPrint = accumE "" (fmap (:) eWritable)

But I'm not sure how to "hold on to" this until enter is pressed, or how to reset it afterwards. What's the right, idomatic way to go about this?


Solution

  • The idea is that eToPrint is sort of a union of two events: when you press characters and when you press enter. Here an example (reactive-banana 0.8):

    eToPrint = accumE "" $ unions [(:) <$> eWritable, const "" <$> eEnter]
    

    To "hold" it, you can use a Behavior.


    Here is a complete solution:

    bString = accumB "" $ unions [(:) <$> eWritable, const "" <$> eEnter]
    eOut    = bString <@ eEnter
    

    The behavior bString contains the accumulated String value. The eOut event returns the last string value whenever the eEnter event happens. Note in particular the semantics of accumB: At the moment in time where eEnter happens, the value of bString is still the old value.