Several very elegant FRP approaches are emerging, most visibly FRP.Reactive,
which rely on blocking on multiple variables at once, continuing when the
*first* of them is available. . . inside an unsafePerformIO, so the
beautiful STM "orElse" solution is not available. The current solution is
to race threads against each other, and have the one that finishes first
kill the other one. This is implemented, for example, in Data.Unamb.
However, our empirical tests have shown that the GHC scheduler is not
*quite* good enough to handle this efficiently, and ends up introducing too
much latency and nondeterminacy.
The Data.IVar<http://hackage.haskell.org/cgi-bin/hackage-scripts/package/data-ivar-0.1>module,
just uploaded to hackage, provides an alternative to thread racing
as a solution to this problem. It provides *write-once* variables which can
be blocked on in parallel, without forking any threads or using STM (so it
is safe to use in unsafePerformIO). Example usage from the documentation:
import qualified Data.IVar as IVar
import Control.Concurrent
main = do
iv <- IVar.new
iv' <- IVar.new
forkIO $ threadDelay 10000000 >> writeIVar iv' "my spoon is too big"
let merger = IVar.read iv `mplus` IVar.read iv'
print =<< IVar.nonblocking merger -- most likely "Nothing"
print =<< IVar.blocking merger -- waits a while, then prints
writeIVar iv' "i am a banana" -- throws error "IVar written twice"
Enjoy!
Luke
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20081007/1375862d/attachment.htm