代码之家  ›  专栏  ›  技术社区  ›  ony

在FRP.Reactive.FieldTrip中使用MonadPlus

  •  2
  • ony  · 技术社区  · 16 年前

    flipflop :: Behavior String
    flipflop = stepper "none" (xflip 2) where
        xflip t0 = do
            t <- withTimeE_ (atTime t0)
            return "flip" `mplus` xflop (t+3)
        xflop t0 = do
            t <- withTimeE_ (atTime t0)
            return "flop" `mplus` xflip (t+2)
    txtGeom = ((uscale2 (0.5::Float) *%) . utext . show <$>)
    main = anim2 (txtGeom . pure flipflop)
    

    问题是:

  • 为什么这个例子会导致内存泄漏?
  • 1 回复  |  直到 16 年前
        1
  •  1
  •   John L    15 年前

    看来以这种方式参加活动是行不通的。请尝试以下操作:

    import FRP.Reactive
    import FRP.Reactive.FieldTrip
    import Graphics.FieldTrip
    import Control.Monad
    import Control.Applicative
    
    
    flipflop = stepper "none" $ either (const "flip") (const "flop")
                <$> eitherE (atTimes ((+2) <$> [0,5..])) (atTimes [5,10..])
    
    txtGeom = ((uscale2 (0.5::Float) *%) . utext . show <$>)
    main = anim2 (txtGeom . pure flipflop)
    

    不幸的是,在这个版本中仍然有一个空间泄漏,但它要小得多。在运行大约一分钟后,RAM的总使用量约为9.7MB。

    还有一个 flipFlop Behavior Bool . 这对触发器很有效,但我没有找到一个干净的方法在前两秒添加“none”。

    我也试过这个

    flipflop = stepper "none" $ (const "flip" <$> (atTimes ((+2) <$> [0,5..])))
                                `mplus` (const "flop" <$> atTimes [5,10..])
    

    当然,这对于以您询问的方式动态地安排时间没有多大作用。不幸的是,我不相信这个用例在被动的环境中工作。

    我非常欣赏这部作品,我也想喜欢它,但这似乎是非常棘手的原因。 This thread 从邮件列表中可以看到这类问题(和解决方案!)这似乎很常见。另外,“unab”库(它是许多反应性代码的基础)暴露了GHC线程中的一些非常微妙的错误,这些错误在GHC-6.12被修复之前对结果造成了很大的破坏。尽管这绝不是Conal或其他被动贡献者的错,但这使得使用该框架变得更加困难,尤其是在早期的GHC框架中。

    你可以试试其他的玻璃钢包装。Yampa有一个很好的实现,我听说了 Elerea demo application .

    推荐文章