never executed always true always false
1 {-# LANGUAGE DeriveDataTypeable #-}
2
3 {- |
4 Module : NITTA.Synthesis.MlBackend.FixedCache
5 Description : Fixed version of thread-safe write-once cache from io-memoize package
6 Copyright : (c) Dan Burton <danburton.email@gmail.com>, 2014
7 License : BSD3
8 Maintainer : aleksandr.penskoi@gmail.com
9 Stability : experimental
10
11 Taken as is from Control.Concurrent.Cache of io-memoize package,
12 but with expoted Cache constructor, so we can use it in pattern matching.
13
14 This was necessary not to rewrite similar functionality. Linter errors were
15 fixed as well.
16 -}
17 module NITTA.Synthesis.MlBackend.FixedCache (Cache (..), newCache, fetch) where
18
19 import Control.Concurrent.MVar
20 import Data.Typeable (Typeable)
21
22 {- | A thread-safe write-once cache. If you need more functionality,
23 (e.g. multiple write, cache clearing) use an 'MVar' instead.
24 -}
25 newtype Cache a = Cache (MVar (Maybe a))
26 deriving (Eq, Typeable)
27
28 {- | Fetch the value stored in the cache,
29 or call the supplied fallback and store the result,
30 if the cache is empty.
31 -}
32 fetch :: Cache a -> IO a -> IO a
33 fetch (Cache var) action = go
34 where
35 go =
36 readMVar var >>= \case
37 Just a -> return a
38 Nothing -> do
39 modifyMVar_ var $ \case
40 Just a -> return (Just a)
41 Nothing -> fmap Just action
42 go
43
44 -- | Create an empty cache.
45 newCache :: IO (Cache a)
46 newCache = do
47 var <- newMVar Nothing
48 return (Cache var)