i would update a Behaviour (Cell / Val) from it's current value.
but the following code throws a thread blocked indefinitely in an MVar operation exception.
i have expected it prints three times 'value of i: '. what did i missing? - thanks.
{-# 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 ()
Your recursive let from RecursiveDo
is in the IO
monad. The Reactive
monad also has a MonadFix
instance. You can define b
completely within Reactive
and then use a sync
around this to execute the entire definition as a transaction.
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)
...
The RecursiveDo
notation isn't helping with an example this simple. The same thing can be written more easily in terms of 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)
...
It's probably worth mentioning that creating a Behavior
from an Event
is usually done with accum
.
b <- sync $ accum 0 (const (+1) <$> e)
In sodium this is a derived function and is internally defined in terms of hold
, snapshot
, and 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