Haskell:通用 IORef、MVar?

2024-02-28

我创建了以下特定于 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

Prints "hello" once.

我希望(一个小烦恼)让它在尽可能多的情况下工作(不仅仅是在 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 的替代方案或者比我更好的使用方法?


我重写了一个俗气的小东西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
    ...

然后很容易抽象出你的记忆例程(尽管你可能想替换IORef在这种情况下与MVar.)

[编辑:澄清用语]

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Haskell:通用 IORef、MVar? 的相关文章

随机推荐