希望有人會爲您提供的FRP答案,現在我會告訴你如何做一個反應系統STM。
首先,我們需要顯式聲明事務變量並設置生產者和消費者。本例中的「生產者」爲newFunc
,其中x
和y
生成新的z
。 「消費者」閱讀z
,如果更改則打印。
import Control.Concurrent.STM
import Control.Concurrent
import Control.Monad
f = do
x <- newTVarIO 2
y <- newTVarIO 3
z <- newTVarIO 0
forkIO $ newFunc 2 3 (x,y) z
loop z 0
所以這非常簡單。由於它很簡單,我們來看看線程監控和打印z
。這個概念是我們記得最後一個值是什麼,如果值已經改變,只打印z
。技巧在retry
,這將只喚醒我們的線程,如果TVar
由另一個事務寫入。
loop z zV = do
print zV
v <- atomically $ do
new_zV <- readTVar z
when (zV == new_zV) retry
return zV
loop z v
可以進行讀compare- {重試或計算}的簡單模式是強大的,正是我們所需要的newFunc
。我們將讀取所有的值和retry
,條件是輸入沒有變化並且結果是正確的(根據您的需要進行調整)。
newFunc :: Int -> Int -> (TVar Int , TVar Int) -> TVar Int -> IO()
newFunc xV yV (x, y) z = atomically $ do
newX <- readTVar x
newY <- readTVar y
currZ <- readTVar z
let result = newX * newY
when (newX == xV && newY == yV && currZ == result) retry
writeTVar z result
你到底要達到什麼樣的?什麼是'newVal','newFunc','setVal'等? – Sibi
@Sibi我從我的反應式編程經驗中得出的結論是,'newVal'創建一個可以/將會改變的值(認爲電子表格的一個單元格),'newFunc'創建一個「公式」並將結果存儲在'z'中,這樣結果自動更新當你'setVal'什麼 – jozefg
@sibi jozefg是正確的。您定義它們,它們僅用於說明目的。預期的輸出結果應該清楚我想要實現的目標,我不介意你是否提出了一個有點不同的方法 – Clinton