Nuk*_*Pan 6 haskell threepenny-gui
我真希望我没有走进死胡同。我有一个行为,它给出当前选择的颜色和当前鼠标坐标,然后在单击鼠标时执行任务。该任务涉及查看列表,然后更新该列表中的值,以便稍后检索。我可以“存储”所选颜色这一事实让我希望可以以类似的方式存储列表。我正处于死胡同,不知道如何解决这个问题。非常感谢一些帮助。
\n-- There is a Blue button and a Red button on our UI. Whichever\n-- button was clicked last is our current color selection.\ncolorRedSelected = const ColorRed <$ UI.click redButton\ncolorBlueSelected = const ColorBlue <$ UI.click blueButton\n\n-- we combine both the above Events to create a new one that tells us the current selected color\ncolorSelected = unionWith const colorRedSelected colorBlueSelected\n\n-- accumulate values for our Behaviour, starting with ColorRed selected by default\ncolorMode \xc2\xa0 \xc2\xa0 \xc2\xa0 <- accumB ColorRed modeEvent\n\n-- create a Behaviour\nmouseCoordinate \xc2\xa0 <- stepper (0,0) $ UI.mousemove canvas\n\n-- want to start with the list [1,2,3,4], but this value should change later.\n-- I have 'never' here, as I don't know what else to put here yet.\n\nlistState \xc2\xa0 \xc2\xa0 \xc2\xa0<- accumB ([1,2,3,4]) never\n\n-- Combine the Behaviours, we now have a tuple (chosenColorMode, mouseCoordinateTuple, savedList)\n\nlet choices = (,,) <$> colorMode <*> mouseCoordinate <*> listState\n\n-- Apply the event (of the user clicking the canvas) to the Behaviour,\n-- creating a new Event that returns the above tuple when it fires\xc2\xa0 \xc2\xa0 \n\nmakeChoice = choices <@ UI.click canvas\n\nonEvent makeChoice $ \\(colorMode, (x,y), savedList) -> do\xc2\xa0 \xc2\xa0 \n ...\n -- in this block we use the savedList, and generate a newList.\n -- I want to update the choicePosition behaviour so that the newList\n -- replaces the old savedList.\nRun Code Online (Sandbox Code Playgroud)\n
完全归功于duplode 的回复,我将简单介绍一下它是如何解决的:
假设我们有一个函数可以根据某个值以某种方式修改列表。如何/为什么updateMyList修改列表对于这个解释来说并不重要,我们只需要知道它的类型。对于此示例,我们将确定列表如何更改的值是鼠标坐标元组 (x, y),我们将其作为其第一个参数传递:
updateMyList :: (Double, Double) -> [Integer] -> [Integer]
updateMyList (x, y) oldList = ...
Run Code Online (Sandbox Code Playgroud)
如果我们有一个事件告诉我们用户单击时的鼠标坐标:
mouseCoords :: Behavior (Double, Double)
mouseCoords <- stepper (0,0) $ UI.mousemove canvas
mouseClicked :: Event (Double, Double)
mouseClicked = mouseCoords <@ UI.click canvas -- this is the Event we need
Run Code Online (Sandbox Code Playgroud)
我们需要做的是fmap列表更新函数到mouseClicked:
listChangeEvent = fmap updateMyList mouseClicked
Run Code Online (Sandbox Code Playgroud)
所以我们创建了一个新的事件:当mouseClicked被触发时,鼠标坐标作为第一个参数传递给updateMyList,这就是我们的新事件在该时间戳的值。但这是一个部分应用的函数,updateMyList仍然需要 an[Integer]作为参数,因此,listChangeEvent具有以下类型:
listChangeEvent :: Event ([Integer] -> [Integer])
Run Code Online (Sandbox Code Playgroud)
现在,这是聪明的部分:如果我们使用accumB并指定起始累加器(即我们的起始列表[1,2,3,4]),然后还使用上面的内容listChangeEvent,因为事件accumB从以下位置获取其值:
listState <- accumB ([1,2,3,4]) listChangeEvent
Run Code Online (Sandbox Code Playgroud)
然后该累加器将被传递给 中的函数Event ([Integer] -> [Integer])。这意味着第一次listChangeEvent触发时,updateMyList将通过以下方式调用:
updateMyList (x, y) [1,2,3,4] -- (x, y) being the mouse coordinates at that time
Run Code Online (Sandbox Code Playgroud)
其结果成为中的新累加器值,并且该新列表将用作下一次触发器listState的参数,依此类推。updateMyListlistChangeEvent
我们可以将其用于任何事情,它不一定是我们正在修改的列表。这只是为我们提供了一种用值初始化行为的方法,并且我们可以通过创建相当于 的函数来准确指定如何导出行为的下一个值updateMyList。
| 归档时间: |
|
| 查看次数: |
153 次 |
| 最近记录: |