Haskell:通用IORef,MVar? [英] Haskell: generic IORef, MVar?

查看:256
本文介绍了Haskell:通用IORef,MVar?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我做了以下特定于IO monad的函数:

  memoIO :: MonadIO m => m a  - > IO(m a)
memoIO action = do
ref< - newMVar Nothing
return $ do
x< - 也许action return =<< liftIO(takeMVar ref)
liftIO。 putMVar ref $ Just x
return x

示例用法:

  main :: IO()
main = do
p < - memoIO $ putStrLnhello
p
p

打印 hello 一次。 / p>

我希望(一个宠物狗)能够尽可能多地工作(不仅仅是在IO中)。



我在hackage上发现了stateref,并且它的代码如下所示:

  { - #LANGUAGE FlexibleContexts,FlexibleInstances, MultiParamTypeClasses,Rank2Types,UndecidableInstances# - } 

import Data.MRef

class(NewMRef rma,DefaultMRef rma,PutMRef rma,TakeMRef rma)=> MRef r m a
实例(NewMRef r m a,DefaultMRef r m a,PutMRef r m a,TakeMRef r m a)=> MRef r m a

memo ::(MRef r m(也许a),Monad s)=> (全部×m× - > s×) - > s a - > m(s a)
memo liftFunc action = do
ref< - newDefaultMRef Nothing
return $ do
x< - 也许action return =<< liftFunc(takeDefaultMRef ref)
liftFunc。 putDefaultMRef ref $只是x
返回x

是否有替代stateref或更好的方法使用它比我做了什么?

解决方案

我已经改写了一个俗气的 MonadRef 在几个不同的场合为我自己使用,而有人可能在Hackage上有一个,但我找不到一个不受其他行李妨碍的人。

  class Monad m => MonadRef m其中
类型Ref m :: * - > *
newRef :: a - > Ref a a
writeRef :: Ref m a - > - > m()
readRef :: Ref m a - > ma

实例MonadRef IO其中
类型Ref IO = IORef
newRef = newIORef
writeRef = writeIORef
readRef = writeIORef

实例MonadRef STM其中
类型参考STM = TVar
...


实例MonadRef(ST s)其中
类型Ref(ST s) = STRef s
...

然后很容易将您的memoization例程尽管你可能想用 MVar 替换 IORef 。)



<编辑:澄清了verbage]


I made the following function which is specific for the 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

Example usage:

main :: IO ()
main = do
  p <- memoIO $ putStrLn "hello"
  p
  p

Prints "hello" once.

I would like (a pet peeve) to make it work for as many cases as possible (not just in IO).

I found stateref on hackage and with it my code looks like this:

{-# 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

Is there an alternative for stateref or a better way to use it than I did?

解决方案

I've rewritten a cheesy little MonadRef class on a few separate occasions for my own personal use and someone probably has one on Hackage, but I can't find one that is unencumbered with other baggage.

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
    ...

Then it is easy to abstract away your memoization routine (though you probably want to replace IORef in this context with an MVar.)

[Edit: clarified verbage]

这篇关于Haskell:通用IORef,MVar?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆