首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Haskell:通用IORef,MVar?

Haskell:通用IORef,MVar?
EN

Stack Overflow用户
提问于 2009-07-07 10:47:31
回答 1查看 1.7K关注 0票数 6

我做了以下专门针对IO monad的函数:

代码语言:javascript
复制
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

示例用法:

代码语言:javascript
复制
main :: IO ()
main = do
  p <- memoIO $ putStrLn "hello"
  p
  p

打印"hello“一次。

我希望(一个恼人的问题)让它在尽可能多的情况下工作(不仅仅是在IO中)。

我在hackage上找到了stateref,我的代码看起来像这样:

代码语言:javascript
复制
{-# 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的方法,或者比我用它更好的方法?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2009-07-07 15:51:46

我在几个不同的场合重写了一个俗气的小MonadRef类,供我个人使用,可能有人在Hackage上有一个,但我找不到一个没有其他负担的。

代码语言:javascript
复制
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 )。

编辑:已澄清的版本

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1091629

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档