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..]
スレッド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
時期尚早に成功しますか?