chan-split-0.2.0: Control/Concurrent/Chan/Class.hs
{-# 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)