I really hope I haven't gone down a dead-end here. I have a Behaviour that gives the currently selected Color, and the current mouse coordinates, then carries out a task when the mouse is clicked. That task involves looking at a list and then updating the values in that list, for it to be retrieved later. The fact that I can "store" the selected color gives me hope that storing a list can be done in a similar manner. I'm just at a dead end and not sure how to solve this. Would really appreciate some help.
-- There is a Blue button and a Red button on our UI. Whichever
-- button was clicked last is our current color selection.
colorRedSelected = const ColorRed <$ UI.click redButton
colorBlueSelected = const ColorBlue <$ UI.click blueButton
-- we combine both the above Events to create a new one that tells us the current selected color
colorSelected = unionWith const colorRedSelected colorBlueSelected
-- accumulate values for our Behaviour, starting with ColorRed selected by default
colorMode <- accumB ColorRed modeEvent
-- create a Behaviour
mouseCoordinate <- stepper (0,0) $ UI.mousemove canvas
-- want to start with the list [1,2,3,4], but this value should change later.
-- I have 'never' here, as I don't know what else to put here yet.
listState <- accumB ([1,2,3,4]) never
-- Combine the Behaviours, we now have a tuple (chosenColorMode, mouseCoordinateTuple, savedList)
let choices = (,,) <$> colorMode <*> mouseCoordinate <*> listState
-- Apply the event (of the user clicking the canvas) to the Behaviour,
-- creating a new Event that returns the above tuple when it fires
makeChoice = choices <@ UI.click canvas
onEvent makeChoice $ \(colorMode, (x,y), savedList) -> do
...
-- in this block we use the savedList, and generate a newList.
-- I want to update the choicePosition behaviour so that the newList
-- replaces the old savedList.
Full credit to this response from duplode, I'll just go through how it was solved:
Let's say we have a function that modifies a list somehow, depending on some value. How/why
updateMyListmodifies the list doesn't really matter for this explanation, we just need to know its type. For this example, we'll say the value that determines how the list changes is a mouse coordinate tuple (x, y), which we'll pass as its first parameter:If we have an Event that tells us the mouse coordinates when the user clicks:
What we need to do is
fmapthe list-updating function ontomouseClicked:So we've created a new Event: when
mouseClickedis triggered, the mouse coordinates are passed as the first parameter toupdateMyList, and that is the value of our new Event at that timestamp. But this is a partially applied function,updateMyListstill requires an[Integer]as a parameter, so as a result,listChangeEventhas the following type:Now, this is the clever part: if we use
accumBand specify the starting accumulator (i.e. our starting list,[1,2,3,4]), and then also use the abovelistChangeEventas the EventaccumBtakes its value from:Then that accumulator is what will be passed to the function in
Event ([Integer] -> [Integer]). Meaning the first time thelistChangeEventtriggers,updateMyListwill be called with:And the result of that becomes the new accumulator value in
listState, and that new list will be used as the parameter toupdateMyListthe next timelistChangeEventtriggers, and so on.We can use this for anything at all, it doesn't necessarily have to be a list that we're modifying. This just gives us a way to initialize a Behavior with a value, and that we can specify exactly how the next value of the Behavior is derived, by creating a function that is equivalent to
updateMyList.