Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 哈斯克尔:通用IORef,MVar?_Haskell_Types_Ioref - Fatal编程技术网

Haskell 哈斯克尔:通用IORef,MVar?

Haskell 哈斯克尔:通用IORef,MVar?,haskell,types,ioref,Haskell,Types,Ioref,我制作了以下特定于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 有没有比我更好的st

我制作了以下特定于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

有没有比我更好的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
    ...
然后就可以很容易地抽象出您的记忆例程(尽管您可能希望在此上下文中用
MVar
替换
IORef


[编辑:澄清措辞]

看起来您正试图重新发明一部分?(这不是一件坏事,我只是想澄清一下。)我不认为“愤怒”是你所认为的意思。@ephemient:我知道明确分享。但据我所知,这将需要我的代码在共享monad transformer中运行,除非我让它在另一个线程中运行,否则它不适合于GLUT回调(普通IO)。@ShreevatasaR:我在维基百科上反复检查过:“宠物的愤怒是一个小麻烦,人们认为它对他们来说特别烦人”。我从非泛型代码中得到了一点小麻烦。Hackage在“TypeCompose”和“ArrayRef”包(使用hayoo发现)中有类似的实现。呃,我想自给自足是一个错误的术语,我的意思是“没有一堆其他行李”,所以也许“没有其他行李的阻碍”更合适。=)不管怎样,我想只有在实际需要的情况下,我才会去推广它:)
{-# 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
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
    ...