J'ai fait la fonction suivante qui est spécifique pour la monade IO:Haskell: générique 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
Exemple d'utilisation:
main :: IO()
main = do
p <- memoIO $ putStrLn "hello"
p
p
copies "hello
" une fois. Je voudrais (une bête noire) pour le faire fonctionner pour autant de cas que possible (pas seulement dans IO).
Je trouve stateref sur hackage et avec elle mon code ressemble à ceci:
{-# 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
Y at-il une alternative pour stateref ou une meilleure façon de l'utiliser que moi?
Il semble que vous essayons de réinventer une partie de http://sebfisch.github.com/explicit-sharing/? (Ce n'est pas une mauvaise chose, je voudrais juste clarifier.) – ephemient
Je ne pense pas que "bête" signifie ce que vous pensez que cela signifie. – ShreevatsaR
@ephemient: Je connais le partage explicite. Mais si je comprends bien, il faudra que mon code fonctionne à l'intérieur du transformateur monad de partage, qui ne correspondra pas aux callbacks GLUT (IO simple) à moins que je ne le fasse fonctionner dans un autre thread. – yairchu