如何知道是什么导致了行为改变?

How to know what made a behavior change?

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

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

我真的没有任何代码可以展示它,因为我对做什么的所有推测甚至不能用 API* 来写,但我有 [=12= 的上下文] 和(简化):

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 到 select 最后一个条目,但这太糟糕了,即使它会起作用,它也只是在添加新项目和select正在处理它。

我该怎么做?

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

所以我决定从头开始,但这次做得太过了,将整个状态包装在它自己的数据类型中,网络只会驱动它。所以实际上,网络要做的就是根据事件调用网络上的功能,仅此而已。在我看来,它要好得多,因为没有应用程序风格的混乱,所有的功能实际上只是简单的功能,而且它更加模块化(例如,我可以决定根本不使用 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
      ]

之前,我的 length 行充满了 lambda,<$><*>,等等。

现在我只是 rectimate' 并通过 LastAction 看到了变化。
我还像那样非常简单地添加了错误检查。