You might want to take a look at <a href="http://hackage.haskell.org/package/Adaptive">http://hackage.haskell.org/package/Adaptive</a> since it seems really similar to what you are trying to do.  In fact, you might also want to google &#39;Functional Reactive Programming&#39;.<br>
<br>  -- ryan<br><br><div class="gmail_quote">On Thu, Feb 24, 2011 at 10:41 PM, Chris Dew <span dir="ltr">&lt;<a href="mailto:cmsdew@gmail.com">cmsdew@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
Hello, just like everyone else, I have a question about monads.  I&#39;ve<br>
read the tutorials, written one monad myself (not in this email), but<br>
I still consider myself a Haskell beginner.<br>
<br>
* Does GHC eliminate unneeded MVars during compilation?<br>
<br>
I&#39;m expecting that it doesn&#39;t, as that would mean optimising away<br>
ForkIOs, which would be quite a thing to do.  I&#39;ve included example<br>
code below.<br>
<br>
* Is there a monad which allows their automatic elimination of MVars<br>
(or their creation only when necessary)?<br>
<br>
This would be similar to how the IO monad allows you to do purely<br>
functional things with a do block, using let.<br>
<br>
I&#39;ve had a go at a lifting function, which wraps a pure function into<br>
an IO action which forever reads from one MVar and writes to another.<br>
What I&#39;m looking for is some form of Monadic context in which many<br>
pure functions, MVar fillers and MVar consumers could be linked<br>
together, where only the necessary MVars remain (or were created) at<br>
compilation time.<br>
<br>
* Would this be a monad, or a monad transformer?<br>
<br>
* Can you specialise a monad transformer on a single base (in this<br>
case IO) so that you can use forkIO in the bind or return?<br>
<br>
Thanks,<br>
<br>
Chris.<br>
<br>
<br>
module Main (<br>
main<br>
)<br>
where<br>
<br>
import Control.Concurrent (forkIO, MVar, newEmptyMVar, putMVar,<br>
takeMVar, ThreadId, threadDelay)<br>
import Control.Monad (forever)<br>
<br>
stepA :: MVar String -&gt; IO ()<br>
stepA boxa = forever $ do<br>
                      line &lt;- getLine<br>
                      putMVar boxa line<br>
<br>
stepB :: MVar String -&gt; IO ()<br>
stepB boxb = forever $ do<br>
                      line &lt;- takeMVar boxb<br>
                      putStrLn line<br>
<br>
-- This simply wraps a string in brackets.<br>
bracket :: String -&gt; String<br>
bracket x = &quot;(&quot; ++ x ++ &quot;)&quot;<br>
<br>
-- This lifts a function into an action which forever performs the function<br>
-- between the two MVars given.<br>
lft :: (a -&gt; b) -&gt; MVar a -&gt; MVar b -&gt; IO ()<br>
lft f c d = forever $ do<br>
                     x &lt;- takeMVar c<br>
                     putMVar d (f x)<br>
<br>
-- Just like C&#39;s main.<br>
main :: IO ()<br>
main = do<br>
      box &lt;- newEmptyMVar<br>
      box2 &lt;- newEmptyMVar<br>
      forkIO $ stepA box<br>
      forkIO $ lft bracket box box2<br>
      forkIO $ stepB box2<br>
      threadDelay 10000000 -- Sleep for at least 10 seconds before exiting.<br>
<br>
_______________________________________________<br>
Haskell-Cafe mailing list<br>
<a href="mailto:Haskell-Cafe@haskell.org">Haskell-Cafe@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/mailman/listinfo/haskell-cafe</a><br>
</blockquote></div><br>