liblawless 0.21.3 → 0.23.0
raw patch · 7 files changed
+248/−3 lines, 7 filesdep +lifted-asyncdep +stm-chansdep +transformers-basedep ~basePVP ok
version bump matches the API change (PVP)
Dependencies added: lifted-async, stm-chans, transformers-base
Dependency ranges changed: base
API changes (from Hackage documentation)
+ STM.Base: atomically :: MonadBase IO m => STM α -> m α
+ STM.Base: data IO a :: * -> *
+ STM.Base: data STM a :: * -> *
+ STM.Base: instance GHC.Classes.Eq STM.Base.BoundedLength
+ STM.Base: instance GHC.Classes.Ord STM.Base.BoundedLength
+ STM.Base: instance GHC.Enum.Bounded STM.Base.BoundedLength
+ STM.Base: instance GHC.Enum.Enum STM.Base.BoundedLength
+ STM.Base: instance GHC.Num.Num STM.Base.BoundedLength
+ STM.Base: instance GHC.Real.Integral STM.Base.BoundedLength
+ STM.Base: instance GHC.Real.Real STM.Base.BoundedLength
+ STM.Base: instance GHC.Show.Show STM.Base.BoundedLength
+ STM.Base: newEmptyTMVarIO :: MonadBase IO m => m (TMVar a)
+ STM.Base: newTBChan :: Integral l => l -> STM (TBChan a)
+ STM.Base: newTBChanIO :: (MonadBase IO m, Integral l) => l -> m (TBChan a)
+ STM.Base: newTMVarIO :: MonadBase IO m => a -> m (TMVar a)
+ STM.Base: newTVarIO :: MonadBase IO m => a -> m (TVar a)
+ STM.Flag: Flag :: TSem -> Flag
+ STM.Flag: lowerFlag :: Flag -> STM ()
+ STM.Flag: newFlag :: (MonadBase IO m) => m Flag
+ STM.Flag: newtype Flag
+ STM.Flag: run :: MonadBaseControl IO m => m a -> m (Async (StM m a))
+ STM.Flag: waitFlag :: Flag -> STM ()
+ STM.Hub: data Hub a
+ STM.Hub: data HubLength
+ STM.Hub: data Source a
+ STM.Hub: hub :: MonadBase IO m => HubLength -> m (Hub a)
+ STM.Hub: hubEmpty :: MonadBase IO m => (Hub a) -> (m Bool)
+ STM.Hub: hubMsg :: MonadBase IO m => (Hub a) -> (m a)
+ STM.Hub: instance GHC.Classes.Eq STM.Hub.HubLength
+ STM.Hub: instance GHC.Classes.Ord STM.Hub.HubLength
+ STM.Hub: instance GHC.Enum.Bounded STM.Hub.HubLength
+ STM.Hub: instance GHC.Enum.Enum STM.Hub.HubLength
+ STM.Hub: instance GHC.Num.Num STM.Hub.HubLength
+ STM.Hub: instance GHC.Real.Integral STM.Hub.HubLength
+ STM.Hub: instance GHC.Real.Real STM.Hub.HubLength
+ STM.Hub: instance GHC.Show.Show STM.Hub.HubLength
+ STM.Hub: source :: Getter (Hub a) (Source a)
+ STM.Hub: sourceMsg :: MonadBase IO m => Source a -> a -> m ()
+ STM.Scatter: data Gather a
+ STM.Scatter: data Scatter a
+ STM.Scatter: gather :: MonadBase IO m => Getter (Scatter a) (m (Gather a))
+ STM.Scatter: gatherMsg :: MonadBase IO m => Gather a -> m a
+ STM.Scatter: scatter :: MonadBase IO m => m (Scatter a)
+ STM.Scatter: scatterMsg :: MonadBase IO m => Scatter a -> a -> m ()
Files
- Source/IO.hs +2/−1
- Source/STM.hs +21/−0
- Source/STM/Base.hs +65/−0
- Source/STM/Flag.hs +42/−0
- Source/STM/Hub.hs +57/−0
- Source/STM/Scatter.hs +51/−0
- liblawless.cabal +10/−2
Source/IO.hs view
@@ -57,6 +57,7 @@ ) where import Lawless+-- import IO.Base import Control.Monad.IO.Class import qualified System.Path.Directory as D import qualified System.Path.IO as PIO@@ -73,7 +74,7 @@ default (Text) --- * Printable I/O to stdio+-- * 'Printable' IO to stdio -- | Exception representing a failure to parse a 'Textual'. data ParseError = ParseError {
+ Source/STM.hs view
@@ -0,0 +1,21 @@+{-# Language DataKinds, TemplateHaskell #-}++{-|+Module: STM+Description: Higher-level STM operations.+Copyright: © 2017 All rights reserved.+License: GPL-3+Maintainer: Evan Cofsky <evan@theunixman.com>+Stability: experimental+Portability: POSIX+-}++module STM (+ module STM.Base,+ module STM.Flag,+ module STM.Scatter+ ) where++import STM.Base+import STM.Flag+import STM.Scatter
+ Source/STM/Base.hs view
@@ -0,0 +1,65 @@+{-|+Module: STM.Base+Description: Lifted STM operations.+Copyright: © 2017 All rights reserved.+License: GPL-3+Maintainer: Evan Cofsky <evan@theunixman.com>+Stability: experimental+Portability: POSIX+-}++module STM.Base (+ module IO.Base,+ module Control.Concurrent.STM.TVar,+ module Control.Concurrent.STM.TMVar,+ module Control.Concurrent.STM.TBChan,+ IO,+ STM,+ atomically,+ newTVarIO,+ newTMVarIO,+ newEmptyTMVarIO,+ newTBChanIO,+ newTBChan+ ) where++import Lawless+import IO.Base+import Control.Concurrent.STM (STM)+import qualified Control.Concurrent.STM as STM+import qualified Control.Concurrent.STM.TVar as TVar+import Control.Concurrent.STM.TVar (TVar, readTVar, writeTVar, modifyTVar)+import qualified Control.Concurrent.STM.TMVar as TMVar+import Control.Concurrent.STM.TMVar (TMVar, readTMVar)+import qualified Control.Concurrent.STM.TBChan as TBChan+import Control.Concurrent.STM.TBChan (+ TBChan, readTBChan, writeTBChan, isEmptyTBChan+ )+import Data.Word++-- | 'STM.atomically' lifted to 'MonadBase' 'IO'.+atomically :: MonadBase IO m => STM α -> m α+atomically = liftBase ∘ STM.atomically++-- | 'newTVarIO' at the top level, lifted.+newTVarIO ∷ MonadBase IO m ⇒ a → m (TVar a)+newTVarIO = liftBase ∘ TVar.newTVarIO++-- | 'newTMVarIO' at the top level, lifted.+newTMVarIO ∷ MonadBase IO m ⇒ a → m (TMVar a)+newTMVarIO = liftBase ∘ TMVar.newTMVarIO++-- | 'newTMVarIO' at the top level, lifted.+newEmptyTMVarIO ∷ MonadBase IO m ⇒ m (TMVar a)+newEmptyTMVarIO = liftBase TMVar.newEmptyTMVarIO++newtype BoundedLength = BoundedLength Word64+ deriving (Eq, Ord, Show, Bounded, Enum, Num, Integral, Real)++-- | 'newTBChanIO' at the top level, lifted, only with a saturated length.+newTBChanIO ∷ (MonadBase IO m, Integral l) ⇒ l → m (TBChan a)+newTBChanIO =+ liftBase ∘ TBChan.newTBChanIO ∘ max 0 ∘ fromIntegral++newTBChan ∷ Integral l ⇒ l → STM (TBChan a)+newTBChan = TBChan.newTBChan ∘ max 0 ∘ fromIntegral
+ Source/STM/Flag.hs view
@@ -0,0 +1,42 @@+{-|+Module: STM.Flag+Description: A flag plus a function to run an 'Async' and lower the flag when it's started.+Copyright: © 2017 All rights reserved.+License: GPL-3+Maintainer: Evan Cofsky <evan@theunixman.com>+Stability: experimental+Portability: POSIX+-}++module STM.Flag where++import Lawless+import Control.Concurrent.Async.Lifted+import Control.Concurrent.STM.TSem+import STM.Base++-- | A 'Flag' used for mutexes.+newtype Flag = Flag TSem++-- | Creates a new 'Flag' in the held state.+newFlag ∷ (MonadBase IO m) ⇒ m Flag+newFlag = Flag <$> atomically (newTSem 0)++-- | Waits for a 'Flag' to be unheld.+waitFlag ∷ Flag → STM ()+waitFlag (Flag s) = waitTSem s++-- | Signals a 'Flag' has been released.+lowerFlag ∷ Flag → STM ()+lowerFlag (Flag s) = signalTSem s++-- | Runs @f@ in a new 'Async', waiting for the 'Async' to start+-- before continuing.+run ∷ MonadBaseControl IO m ⇒ m a → m (Async (StM m a))+run f = do+ g ← newFlag+ a ← async $ do+ atomically $ lowerFlag g+ f+ atomically $ waitFlag g+ return a
+ Source/STM/Hub.hs view
@@ -0,0 +1,57 @@+{-|+Module: STM.Hub+Description: Hub's are bounded single-reader-multiple-writer queues.+Copyright: © 2017 All rights reserved.+License: GPL-3+Maintainer: Evan Cofsky <evan@theunixman.com>+Stability: experimental+Portability: POSIX+-}++module STM.Hub (+ HubLength,+ Hub,+ hub,++ hubMsg,+ hubEmpty,++ Source,+ source,+ sourceMsg+ )where++import Lawless+import STM.Base+import Data.Word++-- * The 'Hub'++-- | The length of a 'Hub', guaranteed to be positive.+newtype HubLength = HubLength Word64+ deriving (Eq, Ord, Show, Bounded, Enum, Num, Integral, Real)++-- | The 'Hub' receives the messages from various 'Source's.+newtype Hub a = Hub {unHub ∷ TBChan a}++hub ∷ MonadBase IO m ⇒ HubLength → m (Hub a)+hub l = liftBase $ Hub <$> (newTBChanIO $ fromIntegral l)++hubMsg ∷ MonadBase IO m ⇒ (Hub a) → (m a)+hubMsg = atomically ∘ readTBChan ∘ unHub++hubEmpty ∷ MonadBase IO m ⇒ (Hub a) → (m Bool)+hubEmpty = atomically ∘ isEmptyTBChan ∘ unHub++-- * The 'Source'++-- | A 'Source' attached to a 'Hub' that can send messages to it.+newtype Source a = Source {unSource ∷ TBChan a}++-- | Create a 'Source' attached to a 'Hub'.+source ∷ Getter (Hub a) (Source a)+source = to $ Source ∘ unHub++-- | Send a message to a 'Hub' through a 'Source'.+sourceMsg ∷ MonadBase IO m ⇒ Source a → a → m ()+sourceMsg s = atomically ∘ writeTBChan (unSource s)
+ Source/STM/Scatter.hs view
@@ -0,0 +1,51 @@+{-|+Module: STM.Scatter+Description: Broadcast channel with multiple listeners and memory safety.+Copyright: © 2017 All rights reserved.+License: GPL-3+Maintainer: Evan Cofsky <evan@theunixman.com>+Stability: experimental+Portability: POSIX+-}++module STM.Scatter (+ Scatter,+ scatter,+ scatterMsg,++ Gather,+ gather,+ gatherMsg+ )where++import Lawless+import STM.Base+import Control.Concurrent.STM.TChan++-- * The 'Scatter'++-- | A 'Scatter' is a single source that can broadcast messages+-- to any number of subscribers.+newtype Scatter a = Scatter {unScatter ∷ TChan a}++-- | Creates a new 'Scatter'.+scatter ∷ MonadBase IO m ⇒ m (Scatter a)+scatter = liftBase $ Scatter <$> newTChanIO++-- | Post a message to a 'Scatter' to all the subscribed 'Gather's.+scatterMsg ∷ MonadBase IO m ⇒ Scatter a → a → m ()+scatterMsg s a = atomically $ writeTChan (unScatter s) a++-- * The 'Gather'++-- | A 'Gather' receives copies of all messages posted to the+-- 'Scatter' it was derived from.+newtype Gather a = Gather {unGather ∷ TChan a}++-- | Create a new 'Gather' from a given 'Scatter'.+gather ∷ MonadBase IO m ⇒ Getter (Scatter a) (m (Gather a))+gather = to $ \s → Gather <$> (atomically ∘ dupTChan ∘ unScatter) s++-- | Read a message posted to a 'Gather' by a 'Scatter'.+gatherMsg ∷ MonadBase IO m ⇒ Gather a → m a+gatherMsg g = atomically $ readTChan (unGather g)
liblawless.cabal view
@@ -1,5 +1,5 @@ name: liblawless-version: 0.21.3+version: 0.23.0 synopsis: Prelude based on protolude for GHC 8 and beyond. license: GPL-3 license-file: LICENSE@@ -29,7 +29,7 @@ source-repository this type: git location: https://gitlab.com/theunixman/liblawless.git- tag: v0.21.3+ tag: v0.23.0 library ghc-options: -Wall -Wno-redundant-constraints -Wno-type-defaults -O2@@ -49,6 +49,11 @@ Parser Path Set+ STM+ STM.Base+ STM.Flag+ STM.Hub+ STM.Scatter Text Text.IO Textual@@ -96,6 +101,7 @@ exceptions >= 0.8.3 && < 0.9, hjsonschema >= 1.6.2 && < 1.7, lens >= 4.14 && < 4.16,+ lifted-async >= 0.9.1.1 && < 0.10, machines >= 0.6.1 && < 0.7, managed >= 1.0.5 && < 1.1, monad-control >= 1.0.1.0 && < 1.1,@@ -108,6 +114,7 @@ random >= 1.1 && < 1.2, semigroups >= 0.18.2 && < 0.19, stm >= 2.4.4 && < 2.5,+ stm-chans >= 3.0.0.4 && < 3.1, stm-containers >= 0.2.15 && < 0.3, QuickCheck >= 2.8 && < 2.10, temporary >= 1.2.0 && < 1.3,@@ -117,6 +124,7 @@ text-printer >= 0.4 && < 0.5, time >= 1.6.0 && < 1.7, transformers >= 0.5.2 && < 0.6,+ transformers-base >= 0.4.4 && < 0.5, zippers >= 0.2.2 && < 0.3 hs-source-dirs: Source default-language: Haskell2010