Следующая, кажется, работает (например: он продолжает говорить Surely tomorrow
каждую секунду)
import Control.Concurrent
import Control.Concurrent.MVar
import Control.Exception (evaluate)
main :: IO()
main = do
godot <- newEmptyMVar
forkIO $ do
g <- evaluate $ last [0..]
putMVar godot g
let loop = do
threadDelay $ 10^6
g <- tryTakeMVar godot
case g of
Just g -> return()
Nothing -> putStrLn "Surely tomorrow." >> loop
loop
Это использует evaluate
для обеспечения last [0..]
фактически вынужден WHFN перед заполнением MVar
- если я изменю раздвоенный нить
forkIO $ do
let g = last [0..]
putMVar godot g
затем программа завершается.
Однако evaluate
использует seq
. В контексте детерминированного параллелизма всегда подчеркивается, что seq
недостаточно, чтобы фактически гарантировать порядок оценки. Не возникает эта проблема в монадической контексте или я должен лучше использовать
forkIO $ do
let g = last [0..]
g `pseq` putMVar godot g
, чтобы обеспечить компилятор не может изменить порядок оценки так tryTakeMVar
преуспевает преждевременно?