Как работает `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 работают аналогично.