io-memoize 1.1.0.0 → 1.1.1.0
raw patch · 2 files changed
+28/−24 lines, 2 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ Control.Concurrent.Cache: instance Eq (Cache a)
+ Control.Concurrent.Cache: instance Typeable1 Cache
Files
- io-memoize.cabal +6/−3
- src/Control/Concurrent/Cache.hs +22/−21
io-memoize.cabal view
@@ -1,5 +1,5 @@ name: io-memoize-version: 1.1.0.0+version: 1.1.1.0 synopsis: Memoize IO actions description: Transform an IO action into a similar IO action@@ -10,7 +10,7 @@ . (1) lazily (might never be performed) .- (2) eagerly (concurrent)+ (2) eagerly (concurrently performed) . Special thanks to shachaf and headprogrammingczar from #haskell irc for helping me reason about the behavior of this library.@@ -22,6 +22,9 @@ maintainer: danburton.email@gmail.com copyright: (c) 2014 Dan Burton +homepage: https://github.com/DanBurton/io-memoize+bug-reports: https://github.com/DanBurton/io-memoize/issues+ category: System build-type: Simple cabal-version: >=1.8@@ -39,4 +42,4 @@ source-repository this type: git location: git://github.com/DanBurton/io-memoize- tag: io-memoize-1.0.0.0+ tag: io-memoize-1.1.1.0
src/Control/Concurrent/Cache.hs view
@@ -1,29 +1,30 @@+{-# LANGUAGE DeriveDataTypeable #-} module Control.Concurrent.Cache (Cache, newCache, fetch) where import Control.Concurrent.MVar-import Data.IORef+import Control.Monad (liftM)+import Data.Typeable (Typeable) --- | A thread-safe write-once cache.-newtype Cache a = Cache {- -- | Fetch the value stored in the cache,- -- or call the supplied fallback and store the result,- -- if the cache is empty.- fetch :: IO a -> IO a-}+-- | A thread-safe write-once cache. If you need more functionality,+-- (e.g. multiple write, cache clearing) use an 'MVar' instead.+newtype Cache a = Cache (MVar (Maybe a))+ deriving (Eq, Typeable) +-- | Fetch the value stored in the cache,+-- or call the supplied fallback and store the result,+-- if the cache is empty.+fetch :: Cache a -> IO a -> IO a+fetch (Cache var) action = go where+ go = readMVar var >>= \m -> case m of+ Just a -> return a+ Nothing -> do+ modifyMVar_ var $ \m' -> case m' of+ Just a -> return (Just a)+ Nothing -> liftM Just action+ go+ -- | Create an empty cache. newCache :: IO (Cache a) newCache = do- b <- newMVar True- r <- newIORef undefined- return (cache b r)--cache :: MVar Bool -> IORef a -> Cache a-cache b r = Cache $ \action -> do- modifyMVar_ b $ \isEmpty ->- if isEmpty- then do v <- action- writeIORef r v- return False- else return False- readIORef r+ var <- newMVar Nothing+ return (Cache var)