<div dir="ltr"><div>I believe the intention is to ensure that two threads do not perform the action at the same time. If you look at the implementation of mfix for IO[1], it's using an MVar. I'm not 100% certain, but I think the `cache` function above could be rewritten to use MVars explicitly and avoid both monadic do and unsafe IO functions.<br></div><div><br></div><div>[1] The fixIO function, <a href="https://www.stackage.org/haddock/lts-10.3/base-4.10.1.0/src/System-IO.html#fixIO">https://www.stackage.org/haddock/lts-10.3/base-4.10.1.0/src/System-IO.html#fixIO</a><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Jan 25, 2018 at 11:50 AM, Yotam Ohad <span dir="ltr"><<a href="mailto:yotam2206@gmail.com" target="_blank">yotam2206@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 .8ex;border-left:1px #ccc solid;border-right:1px #ccc solid;padding-left:1ex;padding-right:1ex"><div dir="rtl"><div dir="ltr">Hi,</div><div dir="ltr"><br></div><div dir="ltr">I've been digging around the source code of reactive-banana and I found this <a href="https://github.com/HeinrichApfelmus/reactive-banana/blob/master/reactive-banana/src/Reactive/Banana/Prim/Cached.hs" target="_blank">code</a>: <br><pre>data Cached m a = Cached (m a)

runCached :: Cached m a -> m a
runCached (Cached x) = x

-- | An action whose result will be cached.
-- Executing the action the first time in the monad will
-- execute the side effects. From then on,
-- only the generated value will be returned.
{-# NOINLINE cache #-}
cache :: (MonadFix m, MonadIO m) => m a -> Cached m a
cache m = unsafePerformIO $ do
    key <- liftIO $ newIORef Nothing
    return $ Cached $ do
        ma <- liftIO $ readIORef key    -- read the cached result
        case ma of
            Just a  -> return a         -- return the cached result.
            Nothing -> mdo
                liftIO $                -- write the result already
                    writeIORef key (Just a)
                a <- m                  -- evaluate
                return a<br><br></pre><pre><font face="sans-serif">I'm trying to understand the reasom behind the use of <font face="monospace">mdo<font face="sans-serif">. Can't it be like this:<br></font></font></font></pre><pre><font face="sans-serif"><font face="monospace"><font face="sans-serif"><font face="monospace">do<br>  a <- m<br>  liftIO $ writeIORef key (Just a)<br>  return a<br></font></font></font></font></pre><pre><font face="sans-serif"><font face="monospace"><font face="sans-serif"><font face="monospace"><font face="sans-serif">Removing the need for a recursive definition?<span class="HOEnZb"><font color="#888888"><br><br></font></span></font></font></font></font></font></pre><span class="HOEnZb"><font color="#888888"><pre><font face="sans-serif"><font face="monospace"><font face="sans-serif"><font face="monospace"><font face="sans-serif">Yotam<br></font></font></font></font></font></pre></font></span></div>

</div>
<br>______________________________<wbr>_________________<br>
Haskell-Cafe mailing list<br>
To (un)subscribe, modify options or view archives go to:<br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-<wbr>bin/mailman/listinfo/haskell-<wbr>cafe</a><br>
Only members subscribed via the mailman list are allowed to post.<br></blockquote></div><br></div>