如何知道导致行为改变的原因?

时间:2015-07-02 03:53:56

标签: haskell frp reactive-banana

我正在编写一个列表框逻辑的网络描述 这很简单:我有一个(Maybe)当前所选项目的行为,我想要它,以便每当用户向列表中添加新项目时,当前所选项目将选择刚刚创建的值。

用户也可以从列表中删除项目,并导致其他各种更改,因此我必须知道何时创建新项目;我不能只选择每次更改的最后一项。

我真的没有任何代码可以显示,因为我对所做的所有猜测都不能用API *编写,但我有Frameworks t和(简化)的上下文:

bDb :: Behavior t [Entry] -- Created with accumB.
bSelected :: Behavior t (Maybe Entry) -- Created with accumB.
eAddEntry :: Event t () -- User clicked an add button. Created with fromAddHandler.

*好吧,我确实考虑过使用eAddEntry来选择最后一个条目,但这很糟糕,即使它会起作用,它只是添加新项目和选择它之间的竞赛。“ p>

我该怎么办呢?

1 个答案:

答案 0 :(得分:2)

我在评论中尝试了Cactus的建议,结果发现它无法完成(我必须在changes块的中间绑定let选择行为,列表行为是,但它们相互依赖)。

所以我决定从头再次开始但是这次过度重做,并将整个状态包装在它自己的数据类型中,网络只会驱动它。所以网络真正做的就是根据事件在网络上调用函数,就是这样。事实证明它非常优越,因为没有应用风格的混乱,所有功能实际上只是简单的功能,而且它更模块化(我可以决定根本不使用FRP,而且变化非常小 - - 只需用函数切换触发器;虽然我仍然需要找到放置状态的位置,这可能是不合适的IORef}。

它很干净,看起来与此类似:

data DbState = DbState Database SelectedItem LastAction Etc Etc
emptyState :: DbState
stateRemove, stateAdd :: DbState -> DbState

,行为只是:

let bDb = accumB emptyState $ unions
      [stateAdd <$ eAddEntry
      ,stateRemove <$ eRemoveEntry
      ]

之前,我的长度线条充满了lambdas,<$><*>等等。

现在我只是rectimate'并通过LastAction查看更改 我还非常简单地添加了错误检查。