tôi đã thực hiện các chức năng sau đó là cụ thể cho các đơn nguyên IO:Haskell: IORef chung, MVar?
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
Ví dụ sử dụng:
main :: IO()
main = do
p <- memoIO $ putStrLn "hello"
p
p
In "hello
" một lần.
Tôi muốn (một chú chó cưng) để làm cho nó hoạt động trong nhiều trường hợp nhất có thể (không chỉ trong IO).
tôi thấy stateref trên hackage và cùng với nó mã của tôi trông như thế này:
{-# 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
Có một sự thay thế cho stateref hoặc một cách tốt hơn để sử dụng nó hơn tôi đã làm?
Dường như bạn đang cố gắng phát minh lại một phần của http://sebfisch.github.com/explicit-sharing/? (Không phải là một điều xấu, tôi chỉ muốn làm rõ.) – ephemient
Tôi không nghĩ rằng "peeve" có nghĩa là những gì bạn nghĩ rằng nó có nghĩa là. – ShreevatsaR
@ephemient: Tôi biết về chia sẻ rõ ràng. Nhưng như tôi hiểu nó sẽ yêu cầu mã của tôi để chạy bên trong biến áp monad chia sẻ, mà sẽ không phù hợp với callback GLUT (đồng bằng IO), trừ khi tôi làm cho nó chạy trong thread khác. – yairchu