それはHaskellで非常に有益ではないだろうが、私はまだモナドとしてTask
Sを実装する方法を示すことができるので、まあ、Haskellは、デフォルトで怠惰を持っています。ここでは、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
インスタンスを定義することができます。
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
を組み合わせることができます。このAPIを使用して
、あなたはちょうどあなたがTask
が実行されたときにフォークしたいアクションを供給することにより、簡単に独自のTask
Sを定義することができます実行する準備ができて新しい繰延タスク:
fork test3
は
Task
を起動し、あなたのC未来を返します実行
test3 :: Task Int
test3 = do
n1 <- test1
n2 <- test2
return (n1 + n2)
結果を要求するためにいつでも呼び出され、完了するまで必要であればブロックされます。
動作することを示すために、2つの簡単なテストを行います。これが正しく動作
main = do
fork test3
getLine -- wait without demanding the future
:まず、私はちょうどそれが正しく複合スレッドを生成を確認するために、将来を要求せずにtest3
をフォークます
$ ./task
Hello,
world!
<Enter>
$
今、私たちは私たちが要求するときに何が起こるかをテストすることができます結果:
main = do
fut <- fork test3
n <- fut -- block until 'test3' is done
print n
...も動作します:
を
Task<T>
のためにC#であなたが
Task<A>
抽出値を取り、結合機能に渡し機能を必要とするので、
Moand m => m a -> (a -> m b) -> m b
:10
Thnaks、まさに私が探していたもの! – Michael