基於我剛纔的問題,其設定我逐漸細化(How to create monadic behaviour in reactive-banana):反應香蕉怎麼辦IO事件正確
假設有eKey
,一個觸發的事件,只要按下一個鍵,Buffer
類型的b
這是隻要在eKey
中發生支持的事件時進行了適當的修改,最後還有一些IO
將對某些事件採取行動。這些IO
動作取決於b
的狀態(爲了簡單起見,假設它們將當前狀態b
打印到控制檯)。
目前,我有這個選擇上的事件發生的動作:
getKeyAction :: KeyVal -> Maybe (IO Buffer -> IO Buffer)
getKeyAction 65288 = Just . liftM $ backspace
getKeyAction 65293 = Just $ \mb -> do
b <- mb
print $ "PRESSED ENTER: " ++ toString b
return emptyBuffer
getKeyAction 65360 = Just . liftM $ leftMost
getKeyAction 65361 = Just . liftM $ left
...
getKeyAction _ = Nothing
,然後我做的:
let
eBufferActions = filterJust $ getKeyAction <$> eKey
bBuffer = accumB (return emptyBuffer) eBufferActions -- model `b`
eBuffer <- changes bBuffer
reactimate' $ fmap displayBuffer <$> eBuffer
一些displayBuffer :: IO Buffer -> IO()
。
它似乎沒有按預期工作。 bBuffer
的狀態似乎在每次事件重新評估時(有效地運行所有事件發生時收集的所有動作),這在我回想起來時是有意義的。
我該如何重構我的代碼才能正確執行此操作? (即IO
行動看緩衝的當前狀態,那麼除了該緩衝區被累積)
如果我能構建一個Event
上適當eKey
事件之際承擔bBuffer
的價值,那麼我可以簡單地映射我的專用IO
動作和reactimate
。你怎麼看?怎麼做? <@
會實現我想要做的事情嗎?但是,我如何將b
與<@
之間的快照映射到Buffer -> IO()
之後,將當前更改推遲到與當前按鍵相關聯的b
?
對我很好。第一步是一切的關鍵。這就是說,我對你的命名約定有點困惑。你爲什麼稱它爲「evalBuffer」?據我所知,「緩衝區」是一個不變的值,你可以通過應用純函數'緩衝區 - >緩衝區'來改變它。 –
'evalBuffer'是一個'IO'動作,它獲取'Buffer'的「當前」狀態並對其進行評估(將緩衝區發送給解釋器並將結果輸出到控制檯)。如果你的意思是'eEval',那就是需要評估的事件。我個人並不支持這個命名,這只是我的第一個想法。 – jakubdaniel