Рекурсивное обновление "Поведения" в Sodium приводит к тому, что "тема заблокирована..."

Я бы обновил поведение (ячейка / значение) с его текущего значения.

но следующий код генерирует поток, заблокированный на неопределенное время в исключении операции 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

1 ответ

Решение

Ваш рекурсивный пусть от RecursiveDo находится в IO монада. Reactive Монада также имеет MonadFix пример. Вы можете определить b полностью внутри Reactive а затем использовать sync вокруг этого, чтобы выполнить все определение как транзакцию.

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 из Event обычно делается с accum,

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

В натрии это производная функция и определяется внутри hold, snapshot, а также 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
Другие вопросы по тегам