This package implements futures and various kinds of concurrency abstractions using futures.
Threads can synchronise their values via futures. Future values are lazily evaluated so they explicitly suspend the computation. Each future object is associated with a background thread that computes the future value. As long as this expression has not been evaluated, the value of the future is unknown. Whenever an unknown future is accessed the computation will suspend on this future. Once the value has been evaluated the computation resumes. A handle is a component that points to an unevaluated future and computes its value on demand. Therefore, handles are used to associate a value to a future. They provide a synchronisation mechanism for processes.
Example This example shows how you can use Buffer to concurrently compute the values of nodes from a binary tree.
data BTree a = BLeaf a | BNode a (BTree a) (BTree a)
concSumB :: (Num a) => BTree a -> IO a concSumB t = do result <- newBuf case t of BLeaf a -> putBuf result a; BNode a t1 t2 -> sumB result t out <- getBuf result return out
sumB :: (Num a) => Buffer a -> BTree a -> IO () sumB mvar tree = do case tree of BLeaf a -> putBuf mvar a BNode a t1 t2 -> do sem <- newBuf forkIO (sumB sem t1) forkIO (sumB sem t2) erg1 <-getBuf sem erg2 <-getBuf sem putBuf mvar (erg1 + erg2 + a)
You can test the function with the following test data
bintree = BNode 1 (BNode 24 (BLeaf 2) (BNode 6 (BLeaf 24) (BLeaf 3)))(BNode 33 (BLeaf 7) (BLeaf 8)) concSumB bintree