{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies #-} 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 with a \"write end\" and a \"read end\". A minimal -- complete instance defines 'readChan' and one of 'writeChan' or -- 'writeList2Chan'. class SplitChan i o | i -> o, o -> i where -- | Read the next value from the 'OutChan'. readChan :: o a -> IO a -- | Write an entire list of items to a chan type writeList2Chan :: i a -> [a] -> IO () writeList2Chan = mapM_ . writeChan -- | Write a value to a Chan type. writeChan :: i a -> a -> IO () writeChan c = writeList2Chan c . return -- | A class for 'SplitChan' types that can be instantiated without programmer -- input. /e.g./ the standard haskell @Chan@ is a member of this class, however -- a bounded chan type that took an @Int@ to define the buffer size would not. class (SplitChan i o)=> NewSplitChan i o where newSplitChan :: IO (i a, o a) -- ------------------------------- -- INSTANCES FOR STANDARD TYPES -- -- ------------------------------- instance SplitChan C.Chan C.Chan where writeList2Chan = C.writeList2Chan writeChan = C.writeChan readChan = C.readChan instance NewSplitChan C.Chan C.Chan where newSplitChan = do c <- C.newChan return (c,c) -- an MVar is a singly-bounded Chan. Think about it. instance SplitChan MVar MVar where writeChan = putMVar readChan = takeMVar instance NewSplitChan MVar MVar where newSplitChan = do v <- newEmptyMVar return (v,v)