斯卡拉 – 事件应该是外部可变的吗?
我正在玩FRP,并且想知道应该如何公开处理事件“发生”的行为.通过这个,我的意思是程序员应该能够在FRP上下文中执行以下操作:
event.occur(now,5) 我从未在任何FRP论文中看到过这样的例子,对我来说感觉不对.我觉得FRP框架应该真正隐藏这种类型的动作,并且事件的发生应该只在幕后发生.我在想这个是正确的吗? 为了澄清,我的方法是“发生”只能由Event类本身访问.如果需要某些外部源的抽象(例如鼠标),可以通过扩展Event类来构建.通过这种方式,所有处理事件创建的逻辑都被抽象出来了. 解决方法
好吧,如果FRP库暴露了一种绑定到外部事件的方式 – 例如现有的基于事件的框架 – 然后它必须提供与此相当的功能,否则它无法与外部世界交互.
但问题是:“外部”是什么意思? FRP系统本身通常被认为是纯粹的,因此从FRP系统内部执行像event.occur(now,5)这样的副作用代码的想法甚至没有意义.通常,当然,提供了响应于FRP事件来执行这样的代码的工具,但是这通常不是作为纯编程模型的一部分,而是作为将网络作为整体与外部世界接口的工具. 因此,在我看来,有两种方法可以解释这个问题: >是否可以从FRP系统外部触发事件? – 肯定是的,因为它是与外界联系所必需的,但这并不影响FRP本身的编程模型. 实际上,即使您明确禁止它,也可能会产生类似#2的内容:考虑进行设置,以便在事件buttonClicked触发时执行switchToWindow 3,例如: (使用reactive-banana表示法): reactimate (switchToWindow 3 <$buttonClicked) 并说我们有一个活动 newWindowFocused :: Event Int 我们设置的反应会导致newWindowFocused事件触发,即使阻止了由于事件而执行的内部代码触发事件. 现在,我到目前为止所说的一切只涉及“外部”事件:那些没有用纯粹的FRP表达的事件,而是明确地创建用于表示在FRP系统之外发生在外部世界的事件.如果你问是否应该有一个设施在纯粹定义的事件中引起特殊事件,那么我的回答是:绝对不是!这破坏了系统的意义,因为突然fmap f(union e1 e2)并不意味着“当e1或e2出现值x”时出现值fx,而是当e1或e2出现时出现值fx值x …或当某些外部代码随机决定触发它时“. 这样的设施不仅对FRP系统的行为进行推理基本上没有意义,1它还违反了引用透明度:如果你构造了两个相当于fmap f(union e1 e2)的事件,那么你可以通过触发一个来区分它们并注意到另一个没有发生.在所有情况下,你根本无法阻止这种情况:想象fmap g(union e1 e2),其中f计算与g相同的函数;功能上的平等是不可判定的:) 当然,完全可以用不纯的语言实现FRP,但我认为提供一种违反FRP系统本身参考透明度的方法是一件非常糟糕的事情,因为它毕竟是一个纯粹的模型. 如果我理解正确,那么你在API中解决这个缺陷的方法(即暴露公开发生,打破了等价事件的引用透明度等等,就像我上面所说的那样)将会发生在你的Event类的内部,所以它不能从外面使用.我同意,如果您需要在内部发生,这是正确的解决方案.我也同意,如果通过子类化Event完成外部事件的实现,将它公开给子类是合理的.这属于“外界粘合剂”,它不属于FRP模型本身的条件,因此完全可以让它以这种方式“打破规则” – 毕竟,这基本上是它的原因:令人不安系统有副作用:) 所以,最后: 不,事件不应暴露此接口. 是的,你认为这是正确的:) 1当然,你可以说外部事件会完全停止,因为系统的整个行为最终取决于连接到外部世界的“边缘”,但事实并非如此:是的,你不能真的假设外部事件本身,但你仍然可以依靠你建立的一切来遵守他们的结构规律.为每个活动提供“外部射击”设施意味着没有任何建筑有任何法律. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |