Ho fatto la seguente funzione che è specifico per la monade IO:Haskell: IORef generico, 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
Esempio Utilizzo:
main :: IO()
main = do
p <- memoIO $ putStrLn "hello"
p
p
stampe "hello
" una volta.
Vorrei (un piccolo cruccio) farlo funzionare per il maggior numero di casi possibile (non solo in IO).
ho trovato stateref su hackage e con esso il mio codice è simile al seguente:
{-# 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
Esiste un'alternativa per stateref o un modo migliore per utilizzarlo di me?
Sembra che tu stanno cercando di reinventare parte di http://sebfisch.github.com/explicit-sharing/? (Non male, vorrei solo chiarire). – ephemient
Non penso che "perbacco" significhi cosa pensi che significhi. – ShreevatsaR
@ephemient: conosco la condivisione esplicita. Ma a quanto ho capito, il mio codice dovrà essere eseguito all'interno del trasformatore di condivisione Monad, che non si adatta ai callback GLUT (I/O semplice) a meno che non lo faccia girare in un'altra discussione. – yairchu