strict-mutable-base (empty) → 1.0.0.0
raw patch · 7 files changed
+340/−0 lines, 7 filesdep +basedep +deepseq
Dependencies added: base, deepseq
Files
- CHANGELOG.md +2/−0
- LICENSE +30/−0
- README.md +13/−0
- src/Control/Concurrent/Chan/Strict.hs +47/−0
- src/Control/Concurrent/MVar/Strict.hs +135/−0
- src/Data/IORef/Strict.hs +64/−0
- strict-mutable-base.cabal +49/−0
+ CHANGELOG.md view
@@ -0,0 +1,2 @@+# strict-mutable-base-1.0.0.0 (2024-09-02)+* Initial release.
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2024, Andrzej Rybczak++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++ * Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.++ * Redistributions in binary form must reproduce the above+ copyright notice, this list of conditions and the following+ disclaimer in the documentation and/or other materials provided+ with the distribution.++ * Neither the name of Andrzej Rybczak nor the names of other+ contributors may be used to endorse or promote products derived+ from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ README.md view
@@ -0,0 +1,13 @@+# strict-mutable-base++[](https://hackage.haskell.org/package/strict-mutable-base)+[](https://github.com/arybczak/strict-mutable/actions?query=branch%3Amaster)+[](https://packdeps.haskellers.com/feed?needle=andrzej@rybczak.net)+[](https://www.stackage.org/lts/package/strict-mutable-base)+[](https://www.stackage.org/nightly/package/strict-mutable-base)++Strict (WHNF) variants of+[Chan](https://hackage.haskell.org/package/base/docs/Control-Concurrent-Chan.html),+[IORef](https://hackage.haskell.org/package/base/docs/Data-IORef.html) and+[MVar](https://hackage.haskell.org/package/base/docs/Control-Concurrent-MVar.html)+for proactive prevention of space leaks.
+ src/Control/Concurrent/Chan/Strict.hs view
@@ -0,0 +1,47 @@+-- | For full documentation please refer to "Control.Concurrent.Chan".+module Control.Concurrent.Chan.Strict+ ( Chan'++ -- * Operations+ , newChan'+ , writeChan'+ , readChan'+ , dupChan'+ , getChanContents'+ , writeList2Chan'+ ) where++import Control.Exception (evaluate)+import qualified Control.Concurrent.Chan as Base++-- | A strict (WHNF) variant of 'Base.Chan'.+newtype Chan' a = Chan' (Base.Chan a)+ deriving Eq++-- | 'Base.newChan' for 'Chan''.+newChan' :: IO (Chan' a)+newChan' = Chan' <$> Base.newChan++-- | 'Base.writeChan' for 'Chan''.+--+-- Evaluates the value to WHNF.+writeChan' :: Chan' a -> a -> IO ()+writeChan' (Chan' chan) a = Base.writeChan chan =<< evaluate a++-- | 'Base.readChan' for 'Chan''.+readChan' :: Chan' a -> IO a+readChan' (Chan' chan) = Base.readChan chan++-- | 'Base.dupChan' for 'Chan''.+dupChan' :: Chan' a -> IO (Chan' a)+dupChan' (Chan' chan) = Chan' <$> Base.dupChan chan++-- | 'Base.getChanContents' for 'Chan''.+getChanContents' :: Chan' a -> IO [a]+getChanContents' (Chan' chan) = Base.getChanContents chan++-- | 'Base.writeList2Chan' for 'Chan''.+--+-- Evaluates the values to WHNF.+writeList2Chan' :: Chan' a -> [a] -> IO ()+writeList2Chan' = mapM_ . writeChan'
+ src/Control/Concurrent/MVar/Strict.hs view
@@ -0,0 +1,135 @@+-- | For full documentation please refer to "Control.Concurrent.MVar".+module Control.Concurrent.MVar.Strict+ ( MVar'++ -- * Operations+ , newEmptyMVar'+ , newMVar'+ , takeMVar'+ , putMVar'+ , readMVar'+ , swapMVar'+ , tryTakeMVar'+ , tryPutMVar'+ , tryReadMVar'+ , isEmptyMVar'+ , withMVar'+ , withMVar'Masked+ , modifyMVar'_+ , modifyMVar'+ , modifyMVar'Masked_+ , modifyMVar'Masked+ , mkWeakMVar'+ ) where++import Control.DeepSeq+import Control.Exception (evaluate)+import GHC.Exts (mkWeak#)+import GHC.IO (IO(..))+import GHC.MVar (MVar(..))+import GHC.Weak (Weak(..))+import qualified Control.Concurrent.MVar as Base++-- | Strict (WHNF) version of 'MVar'.+newtype MVar' a = MVar' (MVar a)+ deriving (Eq, NFData, NFData1)++-- | 'Base.newEmptyMVar' for an 'MVar''.+newEmptyMVar' :: IO (MVar' a)+newEmptyMVar' = MVar' <$> Base.newEmptyMVar++-- | 'Base.newMVar' for an 'MVar''.+--+-- Evaluates the initial value to WHNF.+newMVar' :: a -> IO (MVar' a)+newMVar' a = fmap MVar' . Base.newMVar =<< evaluate a++-- | 'Base.takeMVar' for an 'MVar''.+takeMVar' :: MVar' a -> IO a+takeMVar' (MVar' var) = Base.takeMVar var++-- | 'Base.putMVar' for an 'MVar''.+--+-- Evaluates the new value to WHNF.+putMVar' :: MVar' a -> a -> IO ()+putMVar' (MVar' var) a = Base.putMVar var =<< evaluate a++-- | 'Base.readMVar' for an 'MVar''.+readMVar' :: MVar' a -> IO a+readMVar' (MVar' var) = Base.readMVar var++-- | 'Base.swapMVar' for an 'MVar''.+--+-- Evaluates the new value to WHNF.+swapMVar' :: MVar' a -> a -> IO a+swapMVar' (MVar' var) a = Base.swapMVar var =<< evaluate a++-- | 'Base.tryTakeMVar' for an 'MVar''.+tryTakeMVar' :: MVar' a -> IO (Maybe a)+tryTakeMVar' (MVar' var) = Base.tryTakeMVar var++-- | 'Base.tryPutMVar' for an 'MVar''.+--+-- Evaluates the new value to WHNF.+tryPutMVar' :: MVar' a -> a -> IO Bool+tryPutMVar' (MVar' var) a = Base.tryPutMVar var =<< evaluate a++-- | 'Base.tryReadMVar' for an 'MVar''.+tryReadMVar' :: MVar' a -> IO (Maybe a)+tryReadMVar' (MVar' var) = Base.tryReadMVar var++-- | 'Base.isEmptyMVar' for an 'MVar''.+isEmptyMVar' :: MVar' a -> IO Bool+isEmptyMVar' (MVar' var) = Base.isEmptyMVar var++-- | 'Base.withMVar' for an 'MVar''.+withMVar' :: MVar' a -> (a -> IO b) -> IO b+withMVar' (MVar' var) action = Base.withMVar var action+{-# INLINE withMVar' #-}++-- | 'Base.withMVarMasked' for an 'MVar''.+withMVar'Masked :: MVar' a -> (a -> IO b) -> IO b+withMVar'Masked (MVar' var) action = Base.withMVarMasked var action+{-# INLINE withMVar'Masked #-}++-- | 'Base.modifyMVar_' for an 'MVar''.+--+-- Evaluates the new value to WHNF.+modifyMVar'_ :: MVar' a -> (a -> IO a) -> IO ()+modifyMVar'_ (MVar' var) action = Base.modifyMVar_ var $ \a0 -> do+ a <- action a0+ evaluate a+{-# INLINE modifyMVar'_ #-}++-- | 'Base.modifyMVar' for an 'MVar''.+--+-- Evaluates the new value to WHNF.+modifyMVar' :: MVar' a -> (a -> IO (a, b)) -> IO b+modifyMVar' (MVar' var) action = Base.modifyMVar var $ \a0 -> do+ (a, b) <- action a0+ (, b) <$> evaluate a+{-# INLINE modifyMVar' #-}++-- | 'Base.modifyMVarMasked_' for an 'MVar''.+--+-- Evaluates the new value to WHNF.+modifyMVar'Masked_ :: MVar' a -> (a -> IO a) -> IO ()+modifyMVar'Masked_ (MVar' var) action = Base.modifyMVarMasked_ var $ \a0 -> do+ a <- action a0+ evaluate a+{-# INLINE modifyMVar'Masked_ #-}++-- | 'Base.modifyMVarMasked' for an 'MVar''.+--+-- Evaluates the new value to WHNF.+modifyMVar'Masked :: MVar' a -> (a -> IO (a, b)) -> IO b+modifyMVar'Masked (MVar' var) action = Base.modifyMVarMasked var $ \a0 -> do+ (a, b) <- action a0+ (, b) <$> evaluate a+{-# INLINE modifyMVar'Masked #-}++-- | 'Base.mkWeakMVar' for an 'MVar''.+mkWeakMVar' :: MVar' a -> IO () -> IO (Weak (MVar' a))+mkWeakMVar' var@(MVar' (MVar var#)) (IO finalizer) = IO $ \s0 ->+ case mkWeak# var# var finalizer s0 of+ (# s1, w #) -> (# s1, Weak w #)
+ src/Data/IORef/Strict.hs view
@@ -0,0 +1,64 @@+-- | For full documentation please refer to "Data.IORef".+module Data.IORef.Strict+ ( IORef'++ -- * Operations+ , newIORef'+ , readIORef'+ , writeIORef'+ , modifyIORef'+ , atomicModifyIORef'+ , atomicWriteIORef'+ , mkWeakIORef'+ ) where++import Control.DeepSeq+import Control.Exception (evaluate)+import GHC.Exts (mkWeak#)+import GHC.IO (IO(..))+import GHC.IORef (IORef(..))+import GHC.STRef (STRef(..))+import GHC.Weak (Weak(..))+import qualified Data.IORef as Base++-- | A strict (WHNF) variant of 'IORef'.+newtype IORef' a = IORef' (Base.IORef a)+ deriving (Eq, NFData, NFData1)++-- | 'Base.newIORef' for 'IORef''.+--+-- Evaluates the initial value to WHNF.+newIORef' :: a -> IO (IORef' a)+newIORef' a = fmap IORef' . Base.newIORef =<< evaluate a++-- | 'Base.readIORef' for 'IORef''.+readIORef' :: IORef' a -> IO a+readIORef' (IORef' var) = Base.readIORef var++-- | 'Base.writeIORef' for 'IORef''.+--+-- Evaluates the new value to WHNF.+writeIORef' :: IORef' a -> a -> IO ()+writeIORef' (IORef' var) a = Base.writeIORef var =<< evaluate a++-- | 'Base.modifyIORef' for 'IORef''.+modifyIORef' :: IORef' a -> (a -> a) -> IO ()+modifyIORef' (IORef' var) f = Base.modifyIORef' var f++-- | 'Base.atomicModifyIORef' for 'IORef''.+--+-- Evaluates the new value to WHNF.+atomicModifyIORef' :: IORef' a -> (a -> (a, b)) -> IO b+atomicModifyIORef' (IORef' var) f = Base.atomicModifyIORef' var f++-- | 'Base.atomicWriteIORef' for 'IORef''.+--+-- Evaluates the new value to WHNF.+atomicWriteIORef' :: IORef' a -> a -> IO ()+atomicWriteIORef' (IORef' var) a = Base.atomicWriteIORef var =<< evaluate a++-- | 'Base.mkWeakIORef' for 'IORef''.+mkWeakIORef' :: IORef' a -> IO () -> IO (Weak (IORef' a))+mkWeakIORef' var@(IORef' (IORef (STRef var#))) (IO finalizer) = IO $ \s0 ->+ case mkWeak# var# var finalizer s0 of+ (# s1, w #) -> (# s1, Weak w #)
+ strict-mutable-base.cabal view
@@ -0,0 +1,49 @@+cabal-version: 3.0+build-type: Simple+name: strict-mutable-base+version: 1.0.0.0+homepage: https://github.com/arybczak/strict-mutable+license: BSD-3-Clause+license-file: LICENSE+category: Data+maintainer: andrzej@rybczak.net+author: Andrzej Rybczak++synopsis: Strict variants of mutable data types from @base@.++description: Strict (WHNF) variants of @Chan@, @IORef@ and @MVar@ for proactive+ prevention of space leaks.++extra-doc-files:+ CHANGELOG.md+ README.md++tested-with: GHC == { 8.0.2, 8.2.2, 8.4.4, 8.6.5, 8.8.4, 8.10.7, 9.0.2, 9.2.8, 9.4.8, 9.6.6, 9.8.2, 9.10.1 }++bug-reports: https://github.com/arybczak/strict-mutable/issues+source-repository head+ type: git+ location: https://github.com/arybczak/strict-mutable.git++common language+ ghc-options: -Wall -Wcompat++ default-language: Haskell2010++ default-extensions: GeneralizedNewtypeDeriving+ LambdaCase+ MagicHash+ TupleSections+ UnboxedTuples++library+ import: language++ build-depends: base >=4.9 && < 5+ , deepseq >= 1.4.3.0++ hs-source-dirs: src++ exposed-modules: Control.Concurrent.Chan.Strict+ Control.Concurrent.MVar.Strict+ Data.IORef.Strict