chan-split (empty) → 0.1.2
raw patch · 6 files changed
+260/−0 lines, 6 filesdep +basesetup-changed
Dependencies added: base
Files
- Control/Concurrent/Chan/Class.hs +52/−0
- Control/Concurrent/Chan/Split.hs +76/−0
- Data/Cofunctor.lhs +10/−0
- LICENSE +30/−0
- Setup.hs +2/−0
- chan-split.cabal +90/−0
+ Control/Concurrent/Chan/Class.hs view
@@ -0,0 +1,52 @@+module Control.Concurrent.Chan.Class+ where++import qualified Control.Concurrent.Chan as C+import Control.Concurrent.MVar++{-+ - We create a set of classes for FIFO Chan types, using the function names from+ - Control.Concurrent.Chan, but ommiting deprecated functions.+ - We also omit the 'dupChan' function because it is not central to the Chan+ - concept. Similarly we omit getChanContents as a method, because it is not+ - necessary that every Chan should have a stream interface.+-}+++-- | A class for Chan types that can be written to. A minimum complete+-- instance defines one of 'writeList2Chan' or 'writeChan'+class WritableChan c where+ -- | Write an entire list of items to a chan type+ writeList2Chan :: c a -> [a] -> IO ()+ writeList2Chan = mapM_ . writeChan++ -- | Write a value to a Chan type.+ writeChan :: c a -> a -> IO ()+ writeChan c = writeList2Chan c . return++-- | A class for Chan types that can be read from. +class ReadableChan c where+ -- | Read the next value from the 'OutChan'.+ readChan :: c a -> IO a++++-- -------------------------------+-- INSTANCES FOR STANDARD TYPES --+-- -------------------------------+++instance WritableChan C.Chan where+ writeList2Chan = C.writeList2Chan+ writeChan = C.writeChan++instance ReadableChan C.Chan where+ readChan = C.readChan+++-- an MVar is a bounded Singleton Chan. Think about it.+instance WritableChan MVar where+ writeChan = putMVar++instance ReadableChan MVar where+ readChan = takeMVar
+ Control/Concurrent/Chan/Split.hs view
@@ -0,0 +1,76 @@+{-# LANGUAGE GADTs #-}+module Control.Concurrent.Chan.Split (+ -- * Chan pairs+ newSplitChan+ , InChan()+ , OutChan()+ -- * Utility functions:+ , getChanContents+ , dupChan ++ ) where++import qualified Control.Concurrent.Chan as C+import Data.Cofunctor+import Control.Applicative+import Control.Arrow+-- provided by chan-split:+import Control.Concurrent.Chan.Class++-- TODO: test performance of this with and without fmaped / cofmaped values in+-- comparison with standard Chan. Test to see if we can improve performance+-- using special constructor for fmaped / cofmaped version+++-- | The "write side" of a chan pair+data InChan i where+ InChan :: (i -> a) -> C.Chan a -> InChan i++-- | The "read side" of a chan pair+data OutChan o where+ OutChan :: (a -> o) -> C.Chan a -> OutChan o++-- | Create corresponding read and write ends of a chan pair. Writes to the+-- 'InChan' side can be read on the 'OutChan' side.+newSplitChan :: IO (InChan a, OutChan a)+newSplitChan = (InChan id &&& OutChan id) <$> C.newChan++++instance WritableChan InChan where+ writeChan (InChan f c) = C.writeChan c . f+ writeList2Chan (InChan f c) = C.writeList2Chan c . map f++instance ReadableChan OutChan where+ readChan (OutChan f c) = f <$> C.readChan c ++instance Cofunctor InChan where+ cofmap f' (InChan f c) = InChan (f . f') c++instance Functor OutChan where+ fmap f' (OutChan f c) = OutChan (f' . f) c+++++-- | Return a lazy list representing the contents of the supplied OutChan, much+-- like System.IO.hGetContents.+getChanContents :: OutChan a -> IO [a]+getChanContents (OutChan f c) = map f <$> C.getChanContents c+++-- | Duplicate an 'OutChan': the duplicate channel begins empty, but data+-- written to the corresponding 'InChan' will appear in both, i.e. consuming a+-- value from the copy will have no affect on the values in the original+-- OutChan.+dupChan :: OutChan a -> IO (OutChan a)+dupChan (OutChan f c) = OutChan f <$> C.dupChan c++{-+-- | EXPERIMENTAL: combine multiple output chans, interleaving their values+mergeOutChans :: [OutChan a] -> IO (OutChan a)+mergeOutChans cs = + as <- mapM C.getChanContents cs+ ...+ -}+
+ Data/Cofunctor.lhs view
@@ -0,0 +1,10 @@+> module Data.Cofunctor (+> Cofunctor(..)+> ) where+++This doesn't seem to be a popular class, unfortunately but it's useful for us+here: it lets us transform a Mailbox/sink/processor of one input type to another++> class Cofunctor f where+> cofmap :: (b -> a) -> f a -> f b
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c)2011, Brandon Simmons++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 Brandon Simmons 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.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ chan-split.cabal view
@@ -0,0 +1,90 @@+-- chan-split.cabal auto-generated by cabal init. For additional+-- options, see+-- http://www.haskell.org/cabal/release/cabal-latest/doc/users-guide/authors.html#pkg-descr.+-- The name of the package.+Name: chan-split+Homepage: http://coder.bsimmons.name/blog/2011/07/module-chan-split-released/++-- The package version. See the Haskell package versioning policy+-- (http://www.haskell.org/haskellwiki/Package_versioning_policy) for+-- standards guiding when and how versions should be incremented.+Version: 0.1.2++-- A short (one-line) description of the package.+Synopsis: Concurrent Chans as read/write pairs. Also provides generic+ Chan, Cofunctor classes.++-- A longer description of the package.+Description: A wrapper around Control.Concurrent.Chan that splits a Chan+ into a pair, one of which allows only read operations, the+ other write operations. + .+ This makes code easier to reason about, allows us to define+ useful instances ('Functor' and 'Cofunctor') on the chan+ pairs.+ .+ In addition this package provides a module that defines a+ pair of classes 'ReadableChan' and 'WritableChan' which+ defines the basic methods any Chan type should provide.+ .+ To use standard Chans with these polymorphic functions,+ import as follows:+ .+ > import Control.Concurrent.Chan hiding (readChan,writeChan,writeList2Chan)+ > import Control.Concurrent.Chan.Class+ .+ When used alongside standard Chans, the Split module can be+ imported qualified like:+ .+ > import qualified Control.Concurrent.Chan.Split as S+ .+ Note, we do not implement the deprecated unGetChan and + isEmptyChan functions.+ .+ This module is used internally by the simple-actors package.++-- The license under which the package is released.+License: BSD3++-- The file containing the license text.+License-file: LICENSE++-- The package author(s).+Author: Brandon Simmons++-- An email address to which users can send suggestions, bug reports,+-- and patches.+Maintainer: brandon.m.simmons@gmail.com++-- A copyright notice.+-- Copyright: ++Category: Concurrency++Build-type: Simple++-- Extra files to be distributed with the package, such as examples or+-- a README.+-- Extra-source-files: ++-- Constraint on the version of Cabal needed to build this package.+Cabal-version: >=1.2+++Library+ -- Modules exported by the library.+ Exposed-modules: Control.Concurrent.Chan.Split+ , Control.Concurrent.Chan.Class+ , Data.Cofunctor+ + -- Packages needed in order to build this package.+ Build-depends: base >= 4 && < 5+ + ghc-options: -Wall++ -- Modules not exported by this package.+ -- Other-modules: + + -- Extra tools (e.g. alex, hsc2hs, ...) needed to build the source.+ -- Build-tools: +