chp 1.6.0 → 1.7.0
raw patch · 7 files changed
+272/−82 lines, 7 files
Files
- Control/Concurrent/CHP.hs +2/−0
- Control/Concurrent/CHP/Barriers.hs +51/−73
- Control/Concurrent/CHP/Channels/BroadcastReduce.hs +6/−6
- Control/Concurrent/CHP/Connect.hs +185/−0
- Control/Concurrent/CHP/Enroll.hs +18/−1
- Control/Concurrent/CHP/Utils.hs +6/−0
- chp.cabal +4/−2
Control/Concurrent/CHP.hs view
@@ -40,6 +40,8 @@ -- -- * "Control.Concurrent.CHP.Common" --+-- * "Control.Concurrent.CHP.Connect"+-- -- * "Control.Concurrent.CHP.Console" -- -- * "Control.Concurrent.CHP.Test"
Control/Concurrent/CHP/Barriers.hs view
@@ -64,9 +64,8 @@ -- may query the current phase for any barrier that they are currently enrolled -- on. module Control.Concurrent.CHP.Barriers (Barrier, EnrolledBarrier, newBarrier, newBarrierWithLabel,- PhasedBarrier, newPhasedBarrier, newPhasedBarrierWithLabel, newPhasedBarrierCustomInc,- newPhasedBarrierCustomShowInc, newPhasedBarrierWithLabelCustomInc,- newPhasedBarrierWithLabelCustomShowInc, currentPhase, waitForPhase,+ PhasedBarrier, newPhasedBarrier, newPhasedBarrier', BarOpts(..), defaultIncPhase, defaultBarOpts,+ barLabel, currentPhase, waitForPhase, syncAndWaitForPhase, syncBarrier, getBarrierIdentifier) where import Control.Concurrent.STM@@ -109,6 +108,46 @@ when (ph /= phCur) $ repeatUntil (== ph) (syncBarrier b) +-- | Synchronises on the barrier at least once, until it is in the given phase.+--+-- Note that @syncAndWaitForPhase ph bar == syncBarrier bar >> waitForPhase ph+-- bar@.+--+-- Added in version 1.7.0.+syncAndWaitForPhase :: Eq phase => phase -> Enrolled PhasedBarrier phase -> CHP ()+syncAndWaitForPhase ph = repeatUntil (== ph) . syncBarrier++-- | Options for barrier creation; a function to show the inner data, and an optional+-- label (both only affect tracing). These options can be passed to newPhasedBarrier'.+--+-- Added in version 1.7.0.+data BarOpts phase = BarOpts { barIncPhase :: phase -> phase+ -- ^ Aside from the standard 'defaultIncPhase', you can use succ or (+1) with+ -- Integer as the inner type to get a barrier that never cycles. You can also+ -- do things like supplying (+2) as the incrementing function, or even using+ -- lists as the phase type to do crazy things.+ , barOptsShow :: phase -> String, barOptsLabel :: Maybe String }++-- | The default phase incrementing function. If the phase is already at 'maxBound',+-- it sets it to 'minBound'; otherwise it uses 'succ' to increment the phase.+defaultIncPhase :: (Enum phase, Bounded phase, Eq phase) => phase -> phase+defaultIncPhase p+ | p == maxBound = minBound+ | otherwise = succ p++-- | The default: don't show anything, don't label anything, use Enum+Bounded+Eq to+-- work out the phase increment.+-- +-- Added in version 1.7.0.+defaultBarOpts :: (Enum phase, Bounded phase, Eq phase) => BarOpts phase+defaultBarOpts = BarOpts defaultIncPhase (const "") Nothing++-- | Uses the Show instance for showing the data in traces, and the given label.+--+-- Added in version 1.7.0.+barLabel :: (Enum phase, Bounded phase, Eq phase, Show phase) => String -> BarOpts phase+barLabel = BarOpts defaultIncPhase show . Just+ -- | Creates a new barrier with no processes enrolled newBarrier :: CHP Barrier newBarrier = newPhasedBarrier ()@@ -122,84 +161,23 @@ -- -- The Show constraint was added in version 1.5.0 newPhasedBarrier :: (Enum phase, Bounded phase, Eq phase, Show phase) => phase -> CHP (PhasedBarrier phase)-newPhasedBarrier ph = liftPoison $ liftTrace $ do- tv <- liftIO $ atomically $ newTVar ph- e <- liftIO $ newBarrierEvent show tv - return $ Barrier (e, tv, \p -> if p == maxBound then minBound else succ p)---- | Creates a new barrier with no processes enrolled, that will be on the--- given phase, along with a custom function to increment the phase. You can therefore--- use this function with Integer as the inner type (and succ or (+1) as the incrementing--- function) to get a barrier that never cycles. You can also do things like supplying--- (+2) as the incrementing function, or even using lists as the phase type to--- do crazy things.------ Note that the phase will not show up in the traces -- see--- 'newPhasedBarrierCustomShowInc' for that.-newPhasedBarrierCustomInc :: (phase -> phase) -> phase -> CHP (PhasedBarrier phase)-newPhasedBarrierCustomInc f ph = liftPoison $ liftTrace $ do- tv <- liftIO $ atomically $ newTVar ph- e <- liftIO $ newBarrierEvent (const "") tv- return $ Barrier (e, tv, f)+newPhasedBarrier ph = newPhasedBarrier' ph $ BarOpts defaultIncPhase show Nothing --- | Creates a new barrier with no processes enrolled, that will be on the--- given phase, along with a custom function to show the phase in traces and to--- increment the phase. You can therefore--- use this function with Integer as the inner type (and succ or (+1) as the incrementing--- function, and show as the showing function) to get a barrier that never cycles. You can also do things like supplying--- (+2) as the incrementing function, or even using lists as the phase type to--- do crazy things.------ This function was added in version 1.5.0.-newPhasedBarrierCustomShowInc :: (phase -> String) -> (phase -> phase) -> phase -> CHP (PhasedBarrier phase)-newPhasedBarrierCustomShowInc sh f ph = liftPoison $ liftTrace $ do+-- | Like 'newPhasedBarrier' but allows you to customise the options.+newPhasedBarrier' :: phase -> BarOpts phase -> CHP (PhasedBarrier phase)+newPhasedBarrier' ph (BarOpts incPh showPh label) = liftPoison $ liftTrace $ do tv <- liftIO $ atomically $ newTVar ph- e <- liftIO $ newBarrierEvent sh tv- return $ Barrier (e, tv, f)--+ e <- liftIO $ newBarrierEvent showPh tv + maybe (return ()) (labelEvent e) label+ return $ Barrier (e, tv, incPh) -- | Creates a new barrier with no processes enrolled and labels it in traces -- using the given label. See 'newBarrier'. newBarrierWithLabel :: String -> CHP Barrier-newBarrierWithLabel l = newPhasedBarrierWithLabel l ()---- | Creates a new barrier with no processes enrolled and labels it in traces--- using the given label. See 'newPhasedBarrier'.------ The Show constraint was added in version 1.5.0.-newPhasedBarrierWithLabel :: (Enum phase, Bounded phase, Eq phase, Show phase) => String -> phase -> CHP (PhasedBarrier phase)-newPhasedBarrierWithLabel l ph = liftPoison $ liftTrace $ do- tv <- liftIO $ atomically $ newTVar ph- e <- liftIO $ newBarrierEvent show tv- labelEvent e l- return $ Barrier (e, tv, \p -> if p == maxBound then minBound else succ p)---- | Creates a new barrier with no processes enrolled and labels it in traces--- using the given label. See 'newPhasedBarrierCustomInc'.------ Note that the barrier will not record the phase in the traces -- see--- 'newPhasedBarrierWithLabelCustomShowInc' for that.-newPhasedBarrierWithLabelCustomInc :: String -> (phase -> phase) -> phase -> CHP (PhasedBarrier phase)-newPhasedBarrierWithLabelCustomInc l f ph = liftPoison $ liftTrace $ do- tv <- liftIO $ atomically $ newTVar ph- e <- liftIO $ newBarrierEvent (const "") tv- labelEvent e l- return $ Barrier (e, tv, f)---- | Creates a new barrier with no processes enrolled and labels it in traces--- using the given label and given show function for the phase. See 'newPhasedBarrierWithLabelCustomInc'.------ This function was added in version 1.5.0.-newPhasedBarrierWithLabelCustomShowInc :: String -> (phase -> String) -> (phase -> phase) -> phase -> CHP (PhasedBarrier phase)-newPhasedBarrierWithLabelCustomShowInc l sh f ph = liftPoison $ liftTrace $ do- tv <- liftIO $ atomically $ newTVar ph- e <- liftIO $ newBarrierEvent sh tv- labelEvent e l- return $ Barrier (e, tv, f)-+newBarrierWithLabel = newPhasedBarrier' () . barLabel -- | Gets the identifier of a Barrier. Useful if you want to identify it in -- the trace later on. getBarrierIdentifier :: PhasedBarrier ph -> Unique getBarrierIdentifier (Barrier (e, _, _)) = getEventUnique e+
Control/Concurrent/CHP/Channels/BroadcastReduce.hs view
@@ -89,7 +89,7 @@ -- | The Eq instance was added in version 1.4.0. ----- In versions 1.5.0-1.6.0, the broadcast and reduce channels do not appear correctly+-- In versions 1.5.0-1.7.0, the broadcast and reduce channels do not appear correctly -- in the traces. newtype BroadcastChannel a = BC (Barrier, TVar (Maybe a), ManyToOneTVar Int) @@ -173,14 +173,14 @@ -- | Added in version 1.5.0. ----- In versions 1.5.0-1.6.0, the broadcast and reduce channels do not appear correctly+-- In versions 1.5.0-1.7.0, the broadcast and reduce channels do not appear correctly -- in the traces. oneToManyChannel' :: MonadCHP m => ChanOpts a -> m (OneToManyChannel a) oneToManyChannel' = newChannel' -- | Added in version 1.5.0. ----- In versions 1.5.0-1.6.0, the broadcast and reduce channels do not appear correctly+-- In versions 1.5.0-1.7.0, the broadcast and reduce channels do not appear correctly -- in the traces. anyToManyChannel' :: MonadCHP m => ChanOpts a -> m (AnyToManyChannel a) anyToManyChannel' = newChannel'@@ -188,7 +188,7 @@ -- | The Eq instance was added in version 1.4.0. -- --- In versions 1.5.0-1.6.0, the broadcast and reduce channels do not appear correctly+-- In versions 1.5.0-1.7.0, the broadcast and reduce channels do not appear correctly -- in the traces. newtype ReduceChannel a = GC (Barrier, ManyToOneTVar (Int, Maybe (a, TVar Bool)), (a -> a -> a, a)) @@ -276,14 +276,14 @@ -- | Added in version 1.5.0. -- --- In versions 1.5.0-1.6.0, the broadcast and reduce channels do not appear correctly+-- In versions 1.5.0-1.7.0, the broadcast and reduce channels do not appear correctly -- in the traces. manyToOneChannel' :: (Monoid a, MonadCHP m) => ChanOpts a -> m (ManyToOneChannel a) manyToOneChannel' = const manyToOneChannel --TODO -- | Added in version 1.5.0. -- --- In versions 1.5.0-1.6.0, the broadcast and reduce channels do not appear correctly+-- In versions 1.5.0-1.7.0, the broadcast and reduce channels do not appear correctly -- in the traces. manyToAnyChannel' :: (Monoid a, MonadCHP m) => ChanOpts a -> m (ManyToAnyChannel a) manyToAnyChannel' = const manyToAnyChannel --TODO
+ Control/Concurrent/CHP/Connect.hs view
@@ -0,0 +1,185 @@+-- Communicating Haskell Processes.+-- Copyright (c) 2008--2009, University of Kent.+-- 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 the University of Kent nor the names of its+-- 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.++-- | A module of operators for connecting processes together.+--+-- This whole module was added in version 1.7.0.+module Control.Concurrent.CHP.Connect+ (Connectable(..), (<=>), (|<=>), (<=>|), (|<=>|), pipelineConnect, pipelineConnectComplete,+ cycleConnect, ConnectableExtra(..), connectWith) where++import Control.Applicative+import Control.Arrow++import Control.Concurrent.CHP++-- | Like 'Connectable', but allows an extra parameter.+--+-- The API (and name) for this is still in flux, so do not rely on it just yet.+class ConnectableExtra l r where+ type ConnectableParam l+ -- | Runs the given code with the two items connected.+ connectExtra :: ConnectableParam l -> ((l, r) -> CHP ()) -> CHP ()++-- | Indicates that its two parameters can be joined together automatically.+--+-- Rather than use 'connect' directly, you will want to use the operators such+-- as '(<=>)'. There are different forms of this operator for in the middle of+-- a pipeline (where you still need further parameters to each process), and at+-- the ends. See also 'pipelineConnect' and 'pipelineConnectComplete'.+class Connectable l r where+ -- | Runs the given code with the two items connected.+ connect :: ((l, r) -> CHP ()) -> CHP ()++-- | Joins together the given two processes and runs them in parallel.+(|<=>|) :: Connectable l r => (l -> CHP ()) -> (r -> CHP ()) -> CHP ()+(|<=>|) p q = connect $ \(x, y) -> p x <|*|> q y++jpo :: ConnectableExtra l r => ConnectableParam l -> (l -> CHP ()) -> (r -> CHP ()) -> CHP ()+jpo o p q = connectExtra o $ \(x, y) -> p x <|*|> q y++-- | Joins together the given two processes and runs them in parallel.+(<=>) :: Connectable l r => (a -> l -> CHP ()) -> (r -> b -> CHP ()) -> a -> b -> CHP ()+(<=>) p q x y = p x |<=>| flip q y++-- | Joins together the given two processes and runs them in parallel.+(<=>|) :: Connectable l r => (a -> l -> CHP ()) -> (r -> CHP ()) -> a -> CHP ()+(<=>|) p q x = p x |<=>| q++-- | Joins together the given two processes and runs them in parallel.+(|<=>) :: Connectable l r => (l -> CHP ()) -> (r -> b -> CHP ()) -> b -> CHP ()+(|<=>) p q x = p |<=>| flip q x++-- | Like '(<=>)' but with 'ConnectableExtra'+connectWith :: ConnectableExtra l r => ConnectableParam l ->+ (a -> l -> CHP ()) -> (r -> b -> CHP ()) -> a -> b -> CHP ()+connectWith o p q x y = jpo o (p x) (flip q y)++-- | Like @foldl1 (<=>)@; connects a pipeline of processes together. If the list+-- is empty, it returns a process that ignores both its arguments and returns instantly.+pipelineConnect :: Connectable l r => [r -> l -> CHP ()] -> r -> l -> CHP ()+pipelineConnect [] = const . const $ return ()+pipelineConnect [p] = p+pipelineConnect (p:ps) = p <=> pipelineConnect ps++-- | Connects the given beginning process, the list of middle processes, and+-- the end process into a pipeline and runs them all in parallel. If the list+-- is empty, it connects the beginning directly to the end.+pipelineConnectComplete :: Connectable l r =>+ (l -> CHP ()) -> [r -> l -> CHP ()] -> (r -> CHP ()) -> CHP ()+pipelineConnectComplete begin [] end = begin |<=>| end+pipelineConnectComplete begin middle end+ = (begin |<=> pipelineConnect middle) |<=>| end++-- | Like 'pipelineConnect' but also connects the last process into the first.+-- If the list is empty, it returns immediately.+cycleConnect :: Connectable l r => [r -> l -> CHP ()] -> CHP ()+cycleConnect [] = return ()+cycleConnect ps = connect . uncurry . flip . pipelineConnect $ ps++instance Connectable (Chanout a) (Chanin a) where+ connect = (>>=) ((writer &&& reader) <$> oneToOneChannel)+instance ConnectableExtra (Chanout a) (Chanin a) where+ type ConnectableParam (Chanout a) = ChanOpts a+ connectExtra o = (>>=) ((writer &&& reader) <$> oneToOneChannel' o)++instance Connectable (Chanin a) (Chanout a) where+ connect = (>>=) ((reader &&& writer) <$> oneToOneChannel)+instance ConnectableExtra (Chanin a) (Chanout a) where+ type ConnectableParam (Chanin a) = ChanOpts a+ connectExtra o = (>>=) ((reader &&& writer) <$> oneToOneChannel' o)++instance Connectable (Enrolled PhasedBarrier ()) (Enrolled PhasedBarrier ()) where+ connect m = do b <- newBarrier+ enroll b $ \b0 -> enroll b $ \b1 -> m (b0, b1)++instance ConnectableExtra (Enrolled PhasedBarrier ph) (Enrolled PhasedBarrier ph) where+ type ConnectableParam (Enrolled PhasedBarrier ph) = (ph, BarOpts ph)+ connectExtra (ph, o) m+ = do b <- newPhasedBarrier' ph o+ enroll b $ \b0 -> enroll b $ \b1 -> m (b0, b1)+++instance (Connectable al ar, Connectable bl br) => Connectable (al, bl) (ar, br) where+ connect m = connect $ \(ax, ay) -> connect $ \(bx, by) -> m ((ax, bx), (ay, by))+instance (ConnectableExtra al ar, ConnectableExtra bl br) => ConnectableExtra (al, bl) (ar, br) where+ type ConnectableParam (al, bl) = (ConnectableParam al, ConnectableParam bl)+ connectExtra (ao, bo) m = connectExtra ao $ \(ax, ay) -> connectExtra bo $ \(bx, by) -> m ((ax, bx), (ay, by))++instance (Connectable al ar, Connectable bl br, Connectable cl cr) =>+ Connectable (al, bl, cl) (ar, br, cr) where+ connect m = connect $ \(ax, ay) -> connect $ \(bx, by) ->+ connect $ \(cx, cy) -> m ((ax, bx, cx), (ay, by, cy))++instance (ConnectableExtra al ar, ConnectableExtra bl br, ConnectableExtra cl cr) =>+ ConnectableExtra (al, bl, cl) (ar, br, cr) where+ type ConnectableParam (al, bl, cl) = (ConnectableParam al, ConnectableParam bl, ConnectableParam cl)+ connectExtra (ao, bo, co) m+ = connectExtra ao $ \(ax, ay) -> connectExtra bo $ \(bx, by) ->+ connectExtra co $ \(cx, cy) -> m ((ax, bx, cx), (ay, by, cy))++instance (Connectable al ar, Connectable bl br, Connectable cl cr,+ Connectable dl dr) =>+ Connectable (al, bl, cl, dl) (ar, br, cr, dr) where+ connect m = connect $ \(ax, ay) -> connect $ \(bx, by) ->+ connect $ \(cx, cy) -> connect $ \(dx, dy) ->+ m ((ax, bx, cx, dx), (ay, by, cy, dy))+instance (ConnectableExtra al ar, ConnectableExtra bl br, ConnectableExtra cl cr,+ ConnectableExtra dl dr) =>+ ConnectableExtra (al, bl, cl, dl) (ar, br, cr, dr) where+ type ConnectableParam (al, bl, cl, dl)+ = (ConnectableParam al,+ ConnectableParam bl,+ ConnectableParam cl,+ ConnectableParam dl)+ connectExtra (ao, bo, co, do_) m+ = connectExtra ao $ \(ax, ay) -> connectExtra bo $ \(bx, by) ->+ connectExtra co $ \(cx, cy) -> connectExtra do_ $ \(dx, dy) ->+ m ((ax, bx, cx, dx), (ay, by, cy, dy))++instance (Connectable al ar, Connectable bl br, Connectable cl cr,+ Connectable dl dr, Connectable el er) =>+ Connectable (al, bl, cl, dl, el) (ar, br, cr, dr, er) where+ connect m = connect $ \(ax, ay) -> connect $ \(bx, by) ->+ connect $ \(cx, cy) -> connect $ \(dx, dy) ->+ connect $ \(ex, ey) -> m ((ax, bx, cx, dx, ex), (ay, by, cy, dy, ey))+instance (ConnectableExtra al ar, ConnectableExtra bl br, ConnectableExtra cl cr,+ ConnectableExtra dl dr, ConnectableExtra el er) =>+ ConnectableExtra (al, bl, cl, dl, el) (ar, br, cr, dr, er) where+ type ConnectableParam (al, bl, cl, dl, el)+ = (ConnectableParam al,+ ConnectableParam bl,+ ConnectableParam cl,+ ConnectableParam dl,+ ConnectableParam el)+ connectExtra (ao, bo, co, do_, eo) m+ = connectExtra ao $ \(ax, ay) -> connectExtra bo $ \(bx, by) ->+ connectExtra co $ \(cx, cy) -> connectExtra do_ $ \(dx, dy) ->+ connectExtra eo $ \(ex, ey) -> m ((ax, bx, cx, dx, ex), (ay, by, cy, dy, ey))+
Control/Concurrent/CHP/Enroll.hs view
@@ -31,9 +31,10 @@ -- channels). module Control.Concurrent.CHP.Enroll (Enrolled, Enrollable(..), furtherEnroll,- enrollPair, enrollList) where+ enrollPair, enrollList, enrollAll, enrollAll_) where import Control.Concurrent.CHP.Base+import Control.Concurrent.CHP.Parallel class Enrollable b z where -- | Enrolls on the given barrier, then executes the given function (passing@@ -75,3 +76,19 @@ enrollList [] f = f [] enrollList (b:bs) f = enroll b $ \eb -> enrollList bs $ \ebs -> f (eb:ebs) +-- | Given a command to allocate a new barrier, and a list of processes that use+-- that barrier, enrolls the appropriate number of times (i.e. the list length)+-- and runs all the processes in parallel using that barrier, then returns a list+-- of the results.+--+-- If you have already allocated the barrier, pass @return bar@ as the first parameter.+--+-- Added in version 1.7.0.+enrollAll :: Enrollable b p => CHP (b p) -> [Enrolled b p -> CHP a] -> CHP [a]+enrollAll mbar ps = mbar >>= flip enrollList (runParallel . zipWith ($) ps) . replicate (length ps)++-- | Like enrollAll, but discards the results.+--+-- Added in version 1.7.0.+enrollAll_ :: Enrollable b p => CHP (b p) -> [Enrolled b p -> CHP a] -> CHP ()+enrollAll_ mbar ps = mbar >>= flip enrollList (runParallel_ . zipWith ($) ps) . replicate (length ps)
Control/Concurrent/CHP/Utils.hs view
@@ -35,6 +35,11 @@ -- has channels going in both directions rather than just one, 'dualPipeline' and/or -- '|<->|' can be used. Several other variants on these functions are also provided, -- including operators to use at the beginning and ends of pipelines.+--+-- Most of the functions in this module are superseded or generalised by those+-- in the "Control.Concurrent.CHP.Connect" module since version 1.7.0, so you should+-- look to use those connectors rather than these, as the connects in this module+-- may be removed at some point in the future. module Control.Concurrent.CHP.Utils where import Control.Monad@@ -259,3 +264,4 @@ useBar :: EnrolledBarrier -> CHP a -> CHP a useBar b p = (p <-> (syncBarrier b >> throwPoison)) `onPoisonRethrow` (poison b) -}+
chp.cabal view
@@ -1,5 +1,5 @@ Name: chp-Version: 1.6.0+Version: 1.7.0 Synopsis: An implementation of concurrency ideas from Communicating Sequential Processes License: BSD3 License-file: LICENSE@@ -19,6 +19,7 @@ Homepage: http://www.cs.kent.ac.uk/projects/ofa/chp/ Category: Concurrency +Cabal-Version: >= 1.2.3 Build-Type: Simple Build-Depends: base >= 3 && < 5, extensible-exceptions >= 0.1.1.0, containers, HUnit, mtl, parallel, pretty, QuickCheck >= 2, stm @@ -38,6 +39,7 @@ Control.Concurrent.CHP.Channels.Synonyms Control.Concurrent.CHP.Clocks Control.Concurrent.CHP.Common+ Control.Concurrent.CHP.Connect Control.Concurrent.CHP.Console Control.Concurrent.CHP.Enroll Control.Concurrent.CHP.Monad@@ -61,7 +63,7 @@ Control.Concurrent.CHP.Traces.Base Extensions: ScopedTypeVariables MultiParamTypeClasses- FlexibleInstances+ FlexibleInstances TypeFamilies GeneralizedNewtypeDeriving CPP BangPatterns GHC-Options: -Wall -auto-all