好吧,Haskell有默認懶惰,這樣就不會在Haskell很有指導意義,但我仍然可以說明如何實現Task
S作爲單子。這裏是你將如何實現它們在Haskell:
import Control.Concurrent.Async (async, wait)
newtype Task a = Task { fork :: IO (IO a) }
newTask :: IO a -> Task a
newTask io = Task $ do
w <- async io
return (wait w)
instance Monad Task where
return a = Task $ return (return a)
m >>= f = newTask $ do
aFut <- fork m
a <- aFut
bFut <- fork (f a)
bFut
它建立在async
圖書館爲了方便,但它不就得了。 async
函數所做的就是分叉線程來評估一個動作,返回一個未來。我只是定義一個小包裝,以便我可以定義一個Monad
實例。
使用這個API,你可以很容易地定義自己的Task
S,只是提供你想要當Task
運行到餐桌的操作:
import Control.Concurrent (threadDelay)
test1 :: Task Int
test1 = newTask $ do
threadDelay 1000000 -- Wait 1 second
putStrLn "Hello,"
return 1
test2 :: Task Int
test2 = newTask $ do
threadDelay 1000000
putStrLn " world!"
return 2
然後你就可以使用do
符號它創建結合Task
小號新的延期任務準備運行:
test3 :: Task Int
test3 = do
n1 <- test1
n2 <- test2
return (n1 + n2)
運行fork test3
將產生的Task
並返回一個未來,你ç隨時調用以請求結果,必要時阻塞直到完成。
爲了證明它的工作原理,我會做兩個簡單的測試。首先,我將叉test3
,而不要求其今後的公正,以確保它產生正確複合絲:
main = do
fork test3
getLine -- wait without demanding the future
這正常工作:
$ ./task
Hello,
world!
<Enter>
$
現在,我們可以測試的時候,我們的需求會發生什麼結果:
main = do
fut <- fork test3
n <- fut -- block until 'test3' is done
print n
...這也適用:
$ ./task
Hello,
world!
3
$
Thnaks,正是我在找的! – Michael 2013-04-29 08:04:38