Ich habe die folgende Funktion, die für die IO Monade spezifisch ist:Haskell: generische IORef, MVar?
memoIO :: MonadIO m => m a -> IO (m a)
memoIO action = do
ref <- newMVar Nothing
return $ do
x <- maybe action return =<< liftIO (takeMVar ref)
liftIO . putMVar ref $ Just x
return x
Beispiel Nutzung:
main :: IO()
main = do
p <- memoIO $ putStrLn "hello"
p
p
Prints "hello
" einmal.
Ich möchte (ein Haustier ärgern), damit es für so viele Fälle wie möglich funktioniert (nicht nur in IO).
fand ich stateref auf Hackage und mit ihm mein Code wie folgt aussieht:
{-# LANGUAGE FlexibleContexts, FlexibleInstances, MultiParamTypeClasses, Rank2Types, UndecidableInstances #-}
import Data.MRef
class (NewMRef r m a, DefaultMRef r m a, PutMRef r m a, TakeMRef r m a) => MRef r m a
instance (NewMRef r m a, DefaultMRef r m a, PutMRef r m a, TakeMRef r m a) => MRef r m a
memo :: (MRef r m (Maybe a), Monad s) => (forall x. m x -> s x) -> s a -> m (s a)
memo liftFunc action = do
ref <- newDefaultMRef Nothing
return $ do
x <- maybe action return =<< liftFunc (takeDefaultMRef ref)
liftFunc . putDefaultMRef ref $ Just x
return x
Gibt es eine Alternative für stateref oder einen besseren Weg, es zu benutzen, als ich es tat?
Es sieht aus wie Sie versuchen Teil von http://sebfisch.github.com/explicit-sharing/ neu zu erfinden? (Keine schlechte Sache, ich möchte nur klarstellen.) – ephemient
Ich glaube nicht, dass "Ärgernis" bedeutet, was Sie denken, dass es bedeutet. – ShreevatsaR
@ephemient: Ich weiß über Explicit-Sharing. Aber wie ich es verstehe, erfordert es, dass mein Code innerhalb des Sharing Monad Transformers läuft, der nicht zu GLUT Callbacks passt (plain IO), es sei denn, ich lasse es in einem anderen Thread laufen. – yairchu