Как работает `valueB`? Всегда возвращает одно и то же значение?

Рассмотрим следующий код:

module Main where

import Control.Event.Handler
import Reactive.Banana
import Reactive.Banana.Frameworks

main :: IO ()
main = do
  (addHandler, fire) <- newAddHandler
  compile (network addHandler) >>= actuate
  fire "fire one"
  fire "fire two"

network :: AddHandler String -> MomentIO ()
network addHandler = do
  fireEvent <- fromAddHandler addHandler
  behavior <- stepper "initial stepper value" fireEvent
  behaviorValue <- valueB behavior
  reactimate $ putStrLn . (\v -> "fire input: " ++ show v) <$> fireEvent
  reactimate $ print behaviorValue <$ fireEvent

Выход из этой программы:

fire input: "fire one"
"initial stepper value"
fire input: "fire two"
"initial stepper value"

Я использую valueB правильно? Если нет, что я делаю не так? Какова цель valueB и когда я должен использовать это?

2 ответа

Решение

Это помогает помнить, что Moment (а также MomentIOМонада выражает вычисление, которое происходит в определенный момент времени. Комбинатор valueB просто возвращает значение поведения в тот момент. В вашем случае это в самом начале.

Если вы хотите проверить значение Поведения в разное время, вы можете использовать <@> а также <@ операторы, которые очень похожи на <$> а также <$, Например, заменить последнюю строку на

reactimate $ print <$> behavior <@ fireEvent

будет печатать значение Поведения в каждый момент, когда происходит событие.

Более продвинутое использование будет использовать valueB с execute,

Согласно документации, valueB получает текущее значение данного поведения. Это работает в некоторых MonadMoment, В этом случае этот "момент" - это время создания сети. По этой причине вы всегда получаете одно и то же значение. Вы запрашиваете значение только один раз, в начале.

Вы не можете напрямую реагировать на изменения в поведении, так как они не уведомляют о своих изменениях (это непрерывные сигналы).

Если вы хотите увидеть valueB В бою. я думаю execute Функция - это то, что вам нужно.

execute (valueB <$> stepper "initial stepper value" fireEvent)

Это, конечно, очень надуманный пример, но он должен делать то, что вы хотите.

Кроме того, у меня нет опыта работы с ReactiveBanana, но большинство фреймворков FRP работают аналогично.

Другие вопросы по тегам