2

我会根据当前值更新行为(Cell / Val)。

但以下代码会在 MVar 操作异常中引发无限期阻塞的线程。

我预计它会打印三倍的“我的价值:”。我错过了什么?- 谢谢。

  {-# LANGUAGE RecursiveDo #-}
  module Main where

  import           FRP.Sodium

  main :: IO ()
  main = do
    (e, t) <- sync newEvent

    rec
      b <- sync $ hold 0 $ snapshot (\_ i -> i + 1) e b

    sync $ listen (value b) (\i -> putStrLn $ "value of i: " ++ show i)

    sync $ t "ping"
    sync $ t "ping"
    sync $ t "ping"

    return ()

  • GHCi,版本 7.8.3
  • 钠-0.11.0.3
4

1 回答 1

2

您的递归 let fromRecursiveDoIO单子中。Reactivemonad 也有一个MonadFix实例。您可以在其中b完全定义Reactive,然后sync在此周围使用 a 将整个定义作为事务执行。

main = do
    (e, t) <- sync newEvent

    b <- sync $
        do
            rec
                b <- hold 0 $ snapshot (\_ i -> i + 1) e b
            return b

    sync $ listen (value b) (\i -> putStrLn $ "value of i: " ++ show i)

    ...

这个RecursiveDo符号对这个简单的例子没有帮助。同样的事情可以更容易地用mfix.

main = do
    (e, t) <- sync newEvent

    b <- sync . mfix $ hold 0 . snapshot (\_ i -> i + 1) e

    sync $ listen (value b) (\i -> putStrLn $ "value of i: " ++ show i)

    ...

可能值得一提的是,Behavior从 an创建一个Event通常是用accum.

b <- sync $ accum 0 (const (+1) <$> e)

在钠中,这是一个派生函数,内部用holdsnapshot和定义mfix

accum :: Context r => a -> Event r (a -> a) -> Reactive r (Behavior r a)
accum z efa = do
    rec
        s <- hold z $ snapshot ($) efa s
    return s
于 2015-05-02T19:56:58.767 回答