2016-06-19 106 views
3

考慮下面的代碼:`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)monad表示在特定時刻發生的計算。組合子valueB只是簡單地返回當時行爲的值。就你而言,這是一開始。

如果你想在不同的時間來品嚐行爲的價值,你可以使用<@><@運營商,這是非常相似的<$><$。例如,用

reactimate $ print <$> behavior <@ fireEvent 
替換最後一行

將打印事件觸發時刻的行爲值。

更高級的用法是使用valueBexecute

+0

我終於認識到'valueB'出於某種原因在文檔的「高階」部分,並且它可能最經常與其他更高階的操作(如switchB)一起出現。它是否正確? – Buttons840

+1

@ Buttons840是的,正好。 :-) –

1

根據文檔,valueB獲得給定行爲的當前值。它在一些MonadMoment工作。在這種情況下,這個「時刻」是網絡創建的時間。出於這個原因,你總是得到相同的價值。一開始你只要求價值一次。

你不能直接對行爲的變化做出反應,因爲他們沒有真正地通知他們的變化(他們是連續的信號)。

如果你想看到valueB的行動。我認爲execute功能是你需要的。

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

這當然是一個非常人爲的例子,但它應該做你想做的。

另外,我沒有專門針對ReactiveBanana的經驗,但大多數FRP框架的工作方式都是相似的。

相關問題