packages feed

chp 1.7.1 → 1.8.0

raw patch · 7 files changed

+329/−17 lines, 7 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Control.Concurrent.CHP.Alt: every_ :: [CHP a] -> CHP ()
+ Control.Concurrent.CHP.Behaviours: upTo :: Int -> CHP a -> CHPBehaviour [a]
+ Control.Concurrent.CHP.Connect: connectList :: (Connectable l r) => Int -> ([(l, r)] -> CHP a) -> CHP a
+ Control.Concurrent.CHP.Connect: connectList_ :: (Connectable l r) => Int -> ([(l, r)] -> CHP a) -> CHP ()
+ Control.Concurrent.CHP.Connect: data ChannelPair l r
+ Control.Concurrent.CHP.Connect: instance (Connectable l r) => Connectable (ChannelPair l r) (ChannelPair l r)
+ Control.Concurrent.CHP.Connect: instance (Eq l, Eq r) => Eq (ChannelPair l r)
+ Control.Concurrent.CHP.Connect: instance (Show l, Show r) => Show (ChannelPair l r)
+ Control.Concurrent.CHP.Connect: pipelineConnectCompleteT :: (Connectable l r) => ([a] -> CHP b) -> (l -> a) -> [r -> l -> a] -> (r -> a) -> CHP b
+ Control.Concurrent.CHP.Connect.TwoDim: FourWay :: above -> below -> left -> right -> FourWay above below left right
+ Control.Concurrent.CHP.Connect.TwoDim: FourWayDiag :: aboveLeft -> belowRight -> aboveRight -> belowLeft -> FourWayDiag aboveLeft belowRight aboveRight belowLeft
+ Control.Concurrent.CHP.Connect.TwoDim: above :: FourWay above below left right -> above
+ Control.Concurrent.CHP.Connect.TwoDim: aboveLeft :: FourWayDiag aboveLeft belowRight aboveRight belowLeft -> aboveLeft
+ Control.Concurrent.CHP.Connect.TwoDim: aboveRight :: FourWayDiag aboveLeft belowRight aboveRight belowLeft -> aboveRight
+ Control.Concurrent.CHP.Connect.TwoDim: below :: FourWay above below left right -> below
+ Control.Concurrent.CHP.Connect.TwoDim: belowLeft :: FourWayDiag aboveLeft belowRight aboveRight belowLeft -> belowLeft
+ Control.Concurrent.CHP.Connect.TwoDim: belowRight :: FourWayDiag aboveLeft belowRight aboveRight belowLeft -> belowRight
+ Control.Concurrent.CHP.Connect.TwoDim: data FourWay above below left right
+ Control.Concurrent.CHP.Connect.TwoDim: data FourWayDiag aboveLeft belowRight aboveRight belowLeft
+ Control.Concurrent.CHP.Connect.TwoDim: instance (Eq above, Eq below, Eq left, Eq right) => Eq (FourWay above below left right)
+ Control.Concurrent.CHP.Connect.TwoDim: instance (Eq aboveLeft, Eq belowRight, Eq aboveRight, Eq belowLeft) => Eq (FourWayDiag aboveLeft belowRight aboveRight belowLeft)
+ Control.Concurrent.CHP.Connect.TwoDim: left :: FourWay above below left right -> left
+ Control.Concurrent.CHP.Connect.TwoDim: right :: FourWay above below left right -> right
+ Control.Concurrent.CHP.Connect.TwoDim: type EightWay a b l r al br ar bl = (FourWay a b l r, FourWayDiag al br ar bl)
+ Control.Concurrent.CHP.Connect.TwoDim: wrappedGridEight :: (Connectable above below, Connectable left right, Connectable aboveLeft belowRight, Connectable belowLeft aboveRight) => [[EightWay above below left right aboveLeft belowRight aboveRight belowLeft -> CHP a]] -> CHP [[a]]
+ Control.Concurrent.CHP.Connect.TwoDim: wrappedGridEight_ :: (Connectable above below, Connectable left right, Connectable aboveLeft belowRight, Connectable belowLeft aboveRight) => [[EightWay above below left right aboveLeft belowRight aboveRight belowLeft -> CHP a]] -> CHP ()
+ Control.Concurrent.CHP.Connect.TwoDim: wrappedGridFour :: (Connectable above below, Connectable left right) => [[FourWay above below left right -> CHP a]] -> CHP [[a]]
+ Control.Concurrent.CHP.Connect.TwoDim: wrappedGridFour_ :: (Connectable above below, Connectable left right) => [[FourWay above below left right -> CHP a]] -> CHP ()
+ Control.Concurrent.CHP.Enroll: enrollAllT :: (Enrollable b p) => ([a] -> CHP c) -> CHP (b p) -> [Enrolled b p -> a] -> CHP c
+ Control.Concurrent.CHP.Enroll: enrollOneMany :: (Enrollable b p) => ([Enrolled b p] -> CHP a) -> [(CHP (b p), Enrolled b p -> CHP c)] -> CHP (a, [c])
- Control.Concurrent.CHP.Connect: connect :: (Connectable l r) => ((l, r) -> CHP ()) -> CHP ()
+ Control.Concurrent.CHP.Connect: connect :: (Connectable l r) => ((l, r) -> CHP a) -> CHP a

Files

Control/Concurrent/CHP/Alt.hs view
@@ -101,7 +101,7 @@ -- This only waits for the first action in both (reading from channel c, or writing -- to channel e), not for all of the actions (as, for example, an STM transaction -- would).-module Control.Concurrent.CHP.Alt (alt, (<->), priAlt, (</>), every, (<&>)) where+module Control.Concurrent.CHP.Alt (alt, (<->), priAlt, (</>), every, every_, (<&>)) where  import Control.Arrow import Control.Concurrent.STM@@ -318,6 +318,12 @@     foldM1 :: Monad m => (b -> b -> m b) -> [b] -> m b     foldM1 f (y:ys) = foldM f y ys     foldM1 _ _ = error "Reached unreachable code in every; guards empty in non-empty case"++-- | Like 'every' but discards the results.+--+-- Added in version 1.8.0.+every_ :: [CHP a] -> CHP ()+every_ ps = every ps >> return ()  -- | A useful operator that acts like 'every'.  The operator is associative and -- commutative (see 'every' for notes on idempotence).  When you have lots of things
Control/Concurrent/CHP/Barriers.hs view
@@ -150,7 +150,7 @@  -- | Creates a new barrier with no processes enrolled newBarrier :: CHP Barrier-newBarrier = newPhasedBarrier ()+newBarrier = newPhasedBarrier' () $ BarOpts (const ()) (const "") Nothing  newBarrierEvent :: (phase -> String) -> TVar phase -> IO Event newBarrierEvent sh tv = newEvent (liftM (BarrierSync . sh) $ readTVar tv) 0@@ -174,7 +174,7 @@ -- | Creates a new barrier with no processes enrolled and labels it in traces -- using the given label.  See 'newBarrier'. newBarrierWithLabel :: String -> CHP Barrier-newBarrierWithLabel = newPhasedBarrier' () . barLabel+newBarrierWithLabel = newPhasedBarrier' () . BarOpts (const ()) (const "") . Just  -- | Gets the identifier of a Barrier.  Useful if you want to identify it in -- the trace later on.
Control/Concurrent/CHP/Behaviours.hs view
@@ -32,7 +32,7 @@ -- -- This whole module was added in CHP 1.6.0. module Control.Concurrent.CHP.Behaviours (-  CHPBehaviour, offer, offerAll, alongside, alongside_, endWhen, once, repeatedly, repeatedly_,+  CHPBehaviour, offer, offerAll, alongside, alongside_, endWhen, once, upTo, repeatedly, repeatedly_,   repeatedlyRecurse, repeatedlyRecurse_) where  import Control.Applicative@@ -60,12 +60,26 @@ -- it just won't be offered again during the call to 'offer'.  Thus if you only -- offer some 'once' items without any 'endWhen', then after all the 'once' events -- have happened, the process will deadlock.+--+-- @once m@ can be thought of as a shortcut for @listToMaybe <$> upTo1 m@ once :: CHP a -> CHPBehaviour (Maybe a) once m = CHPBehaviour Nothing (Just $ (\x -> CHPBehaviour (Just x) (Just stop)) <$> m) ++-- | Offers the given behaviour up to the given number of times, returning a list+-- of the results (in chronological order).  Like 'once', when the limit is reached,+-- the call to 'offer' is not terminated, so you still require an 'endWhen'.+--+-- Added in version 1.8.0.+upTo :: Int -> CHP a -> CHPBehaviour [a]+upTo n m = reverse <$> upTo' []+  where+    upTo' xs+      = CHPBehaviour xs $ Just $ if length xs >= n then stop else (upTo' . (:xs)) <$> m+ -- | Repeatedly offers the given behaviour until the outer call to 'offer' is terminated -- by an 'endWhen' event.  A list is returned (in chronological order) of the results--- of each occurrence of the behaviour.+-- of each occurrence of the behaviour.  @repeatedly@ is like an unbounded @upTo@. repeatedly :: forall a. CHP a -> CHPBehaviour [a] repeatedly m = reverse <$> repeatedly' []   where
Control/Concurrent/CHP/Connect.hs view
@@ -32,7 +32,8 @@ -- This whole module was added in version 1.7.0. module Control.Concurrent.CHP.Connect   (Connectable(..), (<=>), (|<=>), (<=>|), (|<=>|), pipelineConnect, pipelineConnectComplete,-    cycleConnect, ConnectableExtra(..), connectWith) where+    pipelineConnectCompleteT, cycleConnect, connectList, connectList_, ChannelPair,+    ConnectableExtra(..), connectWith) where  import Control.Applicative import Control.Arrow@@ -55,8 +56,41 @@ -- 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 ()+  --+  -- The type of this function was generalised in CHP 1.8.0+  -- from @((l, r) -> CHP ()) -> CHP ()@ to @((l, r) -> CHP a) -> CHP a@+  connect :: ((l, r) -> CHP a) -> CHP a +-- | A pair of channels.  The main use of this type is with the Connectable class,+-- as it allows you to wire together two processes that take the exact same channel+-- pair, e.g. both are of type @ChannelPair (Chanin Int) (Chanout Int) -> CHP ()@.  With the+-- normal Connectable pair instances, one would need to be of type @(Chanin Int,+-- Chanout Int) -> CHP ()@, and the other of type @(Chanout Int, Chanin Int) ->+-- CHP ()@.+data ChannelPair l r = ChannelPair l r+  deriving (Eq, Show)++instance Connectable l r => Connectable (ChannelPair l r) (ChannelPair l r) where+  connect f = connect $ \(lx, rx) -> connect $ \(ly, ry) -> +    f (ChannelPair lx ry, ChannelPair ly rx)++-- | Like 'connect', but provides the process a list of items of the specified size,+-- and runs it.+--+-- This function was added in version 1.8.0.+connectList :: Connectable l r => Int -> ([(l, r)] -> CHP a) -> CHP a+connectList n p | n == 0 = p []+                | n > 0 = connect $ \lr -> connectList (n - 1) $ p . (lr :)+                | otherwise = error $ "Control.Concurrent.CHP.Connect.connectList: negative parameter " ++ show n++-- | Like 'connectList' but ignores the results.+--+-- This function was added in version 1.8.0.+connectList_ :: Connectable l r => Int -> ([(l, r)] -> CHP a) -> CHP ()+connectList_ n p | n == 0 = p [] >> return ()+                 | n > 0 = connect $ \lr -> connectList_ (n - 1) $ p . (lr :)+                 | otherwise = error $ "Control.Concurrent.CHP.Connect.connectList_: negative parameter " ++ show n+ -- | 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@@ -85,17 +119,30 @@ -- 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+pipelineConnect ps = foldl1 (<=>) 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+  = (foldl (|<=>) begin middle) |<=>| end++-- | Like 'pipelineConnectComplete' but allows a customised function to run all+-- the processes in parallel.  So @pipelineConnectCompleteT runParallel@ is the+-- same as @pipelineConnectComplete@.  The list of items given to the first function+-- will be in the order: begin process, middle processes, end process, as you would+-- expect.+--+-- This function was added in version 1.8.0.+pipelineConnectCompleteT :: Connectable l r =>+  ([a] -> CHP b) -> (l -> a) -> [r -> l -> a] -> (r -> a) -> CHP b+pipelineConnectCompleteT run begin [] end+  = connect $ \(l, r) -> run [begin l, end r]+pipelineConnectCompleteT run begin (p:ps) end+  = connect $ \(l, r) ->+      pipelineConnectCompleteT (run . (begin l :)) (p r) ps end  -- | Like 'pipelineConnect' but also connects the last process into the first. --  If the list is empty, it returns immediately.
+ Control/Concurrent/CHP/Connect/TwoDim.hs view
@@ -0,0 +1,231 @@+-- 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.++-- | This module contains helper functions for wiring up collections of processes+-- into a two-dimensional arrangement.+--+-- This module was added in version 1.8.0.+module Control.Concurrent.CHP.Connect.TwoDim+  (FourWay(..), wrappedGridFour, wrappedGridFour_,+   FourWayDiag(..), EightWay, wrappedGridEight, wrappedGridEight_) where++import Control.Arrow+import Control.Concurrent.CHP+import Control.Concurrent.CHP.Connect+import Control.Monad+import Data.List++import Prelude hiding (abs)++-- | A data type representing four-way connectivity for a process, with channels+-- to the left and right, above and below.+data FourWay above below left right+  = FourWay { above :: above, below :: below, left :: left, right :: right }+    deriving (Eq)++-- | A data type representing four-way diagonal connectivity for a process, with+-- channels above-left, below-right, above-right and below-left.+data FourWayDiag aboveLeft belowRight aboveRight belowLeft+  = FourWayDiag { aboveLeft :: aboveLeft, belowRight :: belowRight, aboveRight :: aboveRight, belowLeft :: belowLeft }+    deriving (Eq)++-- | EightWay is simply a synonym for a pair of 'FourWay' and 'FourWayDiag'.+type EightWay a b l r al br ar bl  = (FourWay a b l r, FourWayDiag al br ar bl)++-- | Wires the given grid of processes (that require four-way connectivity) together+-- into a wrapped around grid (a torus) and runs them all in parallel.+--+-- The parameter is a list of rows, and should be rectangular (i.e. all the rows+-- should be the same length).  If not, an error will result.  The return value+-- is guaranteed to be the same shape as the input.+--+-- It is worth remembering that if you have only one row or one column (or+-- both), processes can be connected to themselves, so make sure that if a+-- process is connected to itself (e.g. its left channel connects to its right+-- channel), it is coded such that it won't deadlock -- or if needed, checks for this+-- possibility using 'sameChannel'.  Processes may also be connected to each other+-- multiple times -- in a two-wide grid, each process's left channel connects to+-- the same process as its right.+wrappedGridFour :: (Connectable above below, Connectable left right) =>+  [[FourWay above below left right -> CHP a]] -> CHP [[a]]+wrappedGridFour ps+  -- If ps == [], this will succeed, and map connectRowCycle ps will be [],+  -- and thus connectColumnsCycle _ [] will return [] (without forcing the+  -- head call), and it will all work correctly.+  | length (nub $ map length ps) <= 1+     = connectColumnsCycle (length (head ps)) $ map connectRowCycle ps+  | otherwise+     = error $ "Control.Concurrent.CHP.Connect.TwoDim.wrappedGrid: Non-rectangular input "+               ++ " height: " ++ show (length ps) ++ " widths: " ++ show (map length ps)++-- | Like 'wrappedGridFour' but discards the return values.+wrappedGridFour_ :: (Connectable above below, Connectable left right) =>+  [[FourWay above below left right -> CHP a]] -> CHP ()+wrappedGridFour_ ps = wrappedGridFour ps >> return () --TODO fix this++-- | Like 'wrappedGridFour' but provides eight-way connectivity.+--+-- The note on 'wrappedGridFour' about processes being connected to themselves+-- applies here too -- as does the note about processes being connected to+-- each other multiple times.  If you have one row, a process's left,+-- above-left and below-left channels all connect to the same process.  If you+-- have a two-by-two grid, a process's four diagonal channels all connect to+-- the same process.+wrappedGridEight :: (Connectable above below, Connectable left right,+              Connectable aboveLeft belowRight, Connectable belowLeft aboveRight) =>+  [[EightWay above below left right aboveLeft belowRight aboveRight belowLeft -> CHP a]] -> CHP [[a]]+wrappedGridEight ps+  | length (nub $ map length ps) <= 1+     = connectColumnsCycleDiag (length (head ps)) $ map connectRowCycleDiag ps+  | otherwise+     = error $ "Control.Concurrent.CHP.Connect.TwoDim.wrappedGridDiag: Non-rectangular input "+               ++ " height: " ++ show (length ps) ++ " widths: " ++ show (map length ps)++-- | Like 'wrappedGridEight' but discards the output.+wrappedGridEight_ :: (Connectable above below, Connectable left right,+              Connectable aboveLeft belowRight, Connectable belowLeft aboveRight) =>+  [[EightWay above below left right aboveLeft belowRight aboveRight belowLeft -> CHP a]] -> CHP ()+wrappedGridEight_ ps = wrappedGridEight ps >> return ()+++connectRowCycle :: Connectable left right =>+  [FourWay above below left right -> CHP a] -> ([(above, below)] -> CHP [a])+connectRowCycle [] _ = return []+connectRowCycle allps abs = connect $+  foldr connLR+        -- The last process is special because it must take both channels for itself:+        (liftM (:[]) . last allps . uncurry (uncurry FourWay $ last abs))+        (zip (init allps) (init abs))++connLR :: Connectable left right =>+          (FourWay above below left right -> CHP a, (above, below))+       -> ((left, right) -> CHP [a])+       -> ((left, right) -> CHP [a])+connLR (p, (a, b)) q (l, r)+  = liftM (uncurry (:)) . connect $ \(l', r') -> p (FourWay a b l r') <||> q (l', r)++connectColumnsCycle :: Connectable above below => Int -> [[(above, below)] -> CHP [a]] -> CHP [[a]]+connectColumnsCycle _ [] = return []+connectColumnsCycle n ps = connectList n $ foldl1 (connAB n) (map (liftM (:[]) .) ps)++connAB :: Connectable above below => Int -> ([(above, below)] -> CHP [a]) -> ([(above, below)] -> CHP [a]) -> ([(above, below)] -> CHP [a])+connAB n p q abs = liftM (uncurry (++)) $ connectList n $ \abs' -> p (zip (map fst abs) (map snd abs'))+  <||> q (zip (map fst abs') (map snd abs))++connectColumnsCycleDiag :: (Connectable a b, Connectable bl ar, Connectable al br) =>+  Int -> [[((a, b), FourWayDiag al br ar bl)] -> CHP [z]] -> CHP [[z]]+connectColumnsCycleDiag _ [] = return []+connectColumnsCycleDiag n ps = connectList n $ \abs ->+  connectList n $ \leadingDiag -> connectList n $ \otherDiag ->+    foldl1 (connABDiag n) (map (liftM (:[]) .) ps)+      $ zip abs [FourWayDiag al br ar bl+                | (_, ar) <- otherDiag+                | (bl, _) <- shiftRight otherDiag+                | (al, _) <- leadingDiag+                | (_, br) <- shiftLeft leadingDiag]++-- Let's imagine we have a square:+--+-- A B C+-- D E F+-- G H I+--+-- We pass in the outer-most channels as the processes need them to be wired.+--+-- So for example, A will recieve:+-- aboveLeft: AI+-- aboveRight AH+-- belowLeft: AF+-- belowRight: AE+--+-- So for example when we create the leadingDiag channels:+--+-- \1 \2 \3 +-- A  B  C+--+-- The ends are passed to the above channels as-is, but to the below channels shifted lleft:+--+-- G  H  I+-- \2 \3 \1+--+-- For the otherDiag, shifted right when below:+--+-- /1 /2 /3+-- A  B  C+--+-- G  H  I+-- /3 /1 /2++shiftLeft, shiftRight :: [a] -> [a]+shiftLeft [] = []+shiftLeft xs = tail xs ++ [head xs]+shiftRight [] = []+shiftRight xs = last xs : init xs++connABDiag :: (Connectable above below, Connectable al br, Connectable bl ar) =>+  Int -> ([((above, below), FourWayDiag al br ar bl)] -> CHP [a])+  -> ([((above, below), FourWayDiag al br ar bl)] -> CHP [a])+  -> ([((above, below), FourWayDiag al br ar bl)] -> CHP [a])+connABDiag n p q abs = liftM (uncurry (++)) $ connectList n $ \abs' ->+  connectList n $ \leadingDiag -> connectList n $ \otherDiag ->+    p [((a, b), FourWayDiag al br ar bl)+      | ((a, _), _) <- abs+      | (_, b) <- abs'+      | (_, FourWayDiag al _ ar _) <- abs+      | (bl, _) <- shiftRight otherDiag+      | (_, br) <- shiftLeft leadingDiag+      ]+  <||>+    q [((a, b), FourWayDiag al br ar bl)+      | ((_, b), _) <- abs+      | (a, _) <- abs'+      | (al, _) <- leadingDiag+      | (_, ar) <- otherDiag+      | (_, FourWayDiag _ br _ bl) <- abs+      ]+-- We are given our own above and below as we need them to be arranged already.+++connectRowCycleDiag :: Connectable l r =>+  [EightWay a b l r al br ar bl -> CHP z]+  -> ([((a, b), FourWayDiag al br ar bl)] -> CHP [z])+connectRowCycleDiag [] _ = return []+connectRowCycleDiag allps abs = connect $+  foldr connLRDiag+        -- The last process is special because it must take both channels for itself:+        (\lr -> liftM (:[]) $ last allps $ first (($ lr) . uncurry . uncurry FourWay) (last abs))+        (zip (init allps) (init abs))+++connLRDiag :: Connectable l r =>+          (EightWay a b l r al br ar bl -> CHP z, ((a, b), FourWayDiag al br ar bl))+       -> ((l, r) -> CHP [z])+       -> ((l, r) -> CHP [z])+connLRDiag (p, ((a, b), diag)) q (l, r)+  = liftM (uncurry (:)) . connect $ \(l', r') -> p (FourWay a b l r', diag) <||> q (l', r)
Control/Concurrent/CHP/Enroll.hs view
@@ -31,7 +31,7 @@ -- channels).  module Control.Concurrent.CHP.Enroll (Enrolled, Enrollable(..), furtherEnroll,-  enrollPair, enrollList, enrollAll, enrollAll_) where+  enrollPair, enrollList, enrollAll, enrollAll_, enrollAllT, enrollOneMany) where  import Control.Concurrent.CHP.Base import Control.Concurrent.CHP.Parallel@@ -85,10 +85,23 @@ -- -- 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)+enrollAll = enrollAllT runParallel +enrollAllT :: Enrollable b p => ([a] -> CHP c) -> CHP (b p) -> [Enrolled b p -> a] -> CHP c+enrollAllT run mbar ps = mbar >>= flip enrollList (run . zipWith ($) ps) . replicate (length ps)++enrollOneMany :: Enrollable b p => ([Enrolled b p] -> CHP a) -> [(CHP (b p), Enrolled b p -> CHP c)] -> CHP (a, [c])+enrollOneMany p [] = p [] >>= \x -> return (x, [])+enrollOneMany p ((mbar, q) : rest)+  = do bar <- mbar+       enrollPair (bar, bar) $ \(b0, b1) ->+         do ((p', q'), rest') <- enrollOneMany (\bs -> p (b0:bs) <||> q b1) rest+            return (p', q' : rest')+--TODO there is probably a better way to implement the above++ -- | 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)+enrollAll_ = enrollAllT runParallel_
chp.cabal view
@@ -1,12 +1,12 @@ Name:            chp-Version:         1.7.1+Version:         1.8.0 Synopsis:        An implementation of concurrency ideas from Communicating Sequential Processes License:         BSD3 License-file:    LICENSE Author:          Neil Brown Maintainer:      neil@twistedsquare.com Copyright:       Copyright (c) 2008--2009, University of Kent-Stability:       Provisional+Stability:       Stable Tested-with:     GHC==6.8.2, GHC==6.10.1 Description:     The Communicating Haskell Processes (CHP) library is an                  implementation of message-passing concurrency ideas from@@ -40,6 +40,7 @@                  Control.Concurrent.CHP.Clocks                  Control.Concurrent.CHP.Common                  Control.Concurrent.CHP.Connect+                 Control.Concurrent.CHP.Connect.TwoDim                  Control.Concurrent.CHP.Console                  Control.Concurrent.CHP.Enroll                  Control.Concurrent.CHP.Monad@@ -63,7 +64,7 @@                  Control.Concurrent.CHP.Traces.Base  Extensions:      ScopedTypeVariables MultiParamTypeClasses-                 FlexibleInstances TypeFamilies+                 FlexibleInstances TypeFamilies ParallelListComp                  GeneralizedNewtypeDeriving CPP BangPatterns  GHC-Options:     -Wall -auto-all