
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.
[1] The fixIO function,
https://www.stackage.org/haddock/lts-10.3/base-4.10.1.0/src/System-IO.html#f...
On Thu, Jan 25, 2018 at 11:50 AM, Yotam Ohad
Hi,
I've been digging around the source code of reactive-banana and I found this code https://github.com/HeinrichApfelmus/reactive-banana/blob/master/reactive-ban...:
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
I'm trying to understand the reasom behind the use of mdo. Can't it be like this:
do a <- m liftIO $ writeIORef key (Just a) return a
Removing the need for a recursive definition?
Yotam
_______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.