【问题标题】:reactive-banana-wx `sink` does not generate an event enabling post-sink processingreactive-banana-wx `sink` 不会生成启用 post-sink 处理的事件
【发布时间】:2012-11-14 19:57:05
【问题描述】:

我目前正在使用 reactive-banana 和 reactive-banana-wx 包重新设计一个遗留的 wxHaskell。然而,为了避免动态网络构建(我遇到了 MVar 上的线程块),我现在通过预先构建一组固定的 wxHaskell 小部件来模拟这一点,我根据需要设置了这些小部件的可见性。可见性由采用Behaviorsink 函数设置。但是,wxHaskell 要求在通过sink 适当修改所有这些小部件之后,需要随后更改包含这些小部件的面板的布局。这意味着sink-ing 实际上应该是网络的一部分,因此它是一个可以触发并等待布局更改的事件。就目前而言,sink 会将您“带出”事件网络,在 sink 操作完成后无法触发事件。我确实尝试过让sink 适应这样的事情:

sink' :: Frameworks t =>
    w -> [Prop' t w] -> Moment t (Event t ())
sink' widget props = do
    es <- mapM sink1 props
    return $ unions es
  where
    sink1 (attr :== b) = do
        x <- initial b
        liftIOLater $ set widget [attr := x]
        e <- changes b
        return $ (\x -> unsafePerformIO $ set widget [attr := x]) <$> e

但是,unsafePerformIO 没有被执行。如何实现所需的行为,即允许通过Event 等待(wxHaskell)IO?

【问题讨论】:

    标签: haskell reactive-programming frp reactive-banana


    【解决方案1】:

    基本上,您似乎想确保reactimate中的IO操作按一定顺序执行?也就是说,您要确保在设置小部件属性之后设置布局。

    有几种指定顺序的方法:

    1. 使用unionunionWith 和/或collect 来确定同时发生的事件的顺序。
    2. 使用reactimate 是按照它们在Moment monad 中出现的顺序执行的事实。 (虽然严格来说,当您在动态事件切换中使用 observeE 组合子时,这不再适用。)

    在您的特定情况下,可以按如下方式应用这些想法。

    对于1,你可以制作一个包含IO动作的事件,稍后再与布局结合

    sink' :: Frameworks t =>
        w -> [Prop' t w] -> Moment t (Event t (IO ()))
    sink' widget props = do
        es <- mapM sink1 props
        return $ foldr1 (unionWith (>>)) es
      where
        sink1 (attr :== b) = do
            x <- initial b
            liftIOLater $ set widget [attr := x]
            e <- changes b
            return $ (\x -> set widget [attr := x]) <$> e
    

    对于 2,您可以简单地使用普通的 sink 函数,并确保最后设置布局。

    do
        sink widget1 [ visible :== bBool ]
        sink window1 [ layout  :== bLayout ]
    

    monad 中sink 函数的顺序保证了布局是最后设置的。


    还要注意,从响应式香蕉 0.7 开始,您可以使用动态事件切换来对一组可变的小部件进行建模。请参阅BarTab.hs example 进行演示。此示例还设置了布局。

    您表示在使用动态网络时遇到了 MVar 块。这可能是因为您创建小部件的方式会触发网络中的另一个事件。不幸的是,这在语义上是不合理的——它对应的值取决于它们自己的未来版本——并且程序通过陷入谷底来做出响应。

    【讨论】:

    • 谢谢!关于BarTab.hs 示例,我确实复制了它的行为。 BarTab 动态计算小部件列表的增量,该增量独立于前一个列表。然而,我尝试构建的增量确实取决于前面的列表。我猜它在那里出错了,以后可能会重试,也许会引起另一个帖子。
    • 好的,如果有其他内容弹出,请告诉我。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-11-25
    • 2019-10-20
    • 2020-07-26
    • 1970-01-01
    • 1970-01-01
    • 2013-02-16
    • 1970-01-01
    相关资源
    最近更新 更多