This is crude code using transactional variables (i.e. software transactional memory). You can use IORef, MVar, or many other constructs.
main = do
recvFunc <- initNetwork
cntTV <- newTVarIO 0
forkIO $ threadA recvFunc cntTV
runGUI cntTV 0
, cntTV
threadA recvCntFromNetwork cntTVar = forever $ do
cnt <- recvCntFromNetwork
atomically (writeTVar cntTVar cnt)
threadA .
runGUI cntTVar currentCnt = do
counter <- initGUI
cnt <- atomically $ do
cnt <- readTVar cntTVar
if (cnt == currentCnt)
then retry
else return cnt
updateGUICounter counter cnt
runGUI cntTVar cnt
runGUI , , GUI. FYI, runGUI retry , cntTVar , .
, updateGUICounter, initGUI initNetwork. Hoogle, , , .