我做了以下专门针对IO monad的函数:
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示例用法:
main :: IO ()
main = do
p <- memoIO $ putStrLn "hello"
p
p打印"hello“一次。
我希望(一个恼人的问题)让它在尽可能多的情况下工作(不仅仅是在IO中)。
我在hackage上找到了stateref,我的代码看起来像这样:
{-# 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有没有替代stateref的方法,或者比我用它更好的方法?
发布于 2009-07-07 15:51:46
我在几个不同的场合重写了一个俗气的小MonadRef类,供我个人使用,可能有人在Hackage上有一个,但我找不到一个没有其他负担的。
class Monad m => MonadRef m where
type Ref m :: * -> *
newRef :: a -> Ref m a
writeRef :: Ref m a -> -> m ()
readRef :: Ref m a -> m a
instance MonadRef IO where
type Ref IO = IORef
newRef = newIORef
writeRef = writeIORef
readRef = writeIORef
instance MonadRef STM where
type Ref STM = TVar
...
instance MonadRef (ST s) where
type Ref (ST s) = STRef s
...然后很容易抽象出您的记忆例程(尽管您可能希望在此上下文中用MVar替换IORef )。
编辑:已澄清的版本
https://stackoverflow.com/questions/1091629
复制相似问题