Skip to content
Snippets Groups Projects
Commit 333f0f37 authored by sof's avatar sof
Browse files

[project @ 1998-01-22 11:11:46 by sof]

* renamed putList2Chan to writeList2Chan.
* renamed readChanContents to getChanContents
* Use do notation throughout.
parent 3dae85df
No related merge requests found
%
% (c) The GRASP/AQUA Project, Glasgow University, 1995
% (c) The GRASP/AQUA Project, Glasgow University, 1995-97
%
\section[Channel]{Unbounded Channels}
......@@ -21,13 +21,12 @@ module Channel
unGetChan, -- :: Chan a -> a -> IO ()
{- stream interface -}
readChanContents, -- :: Chan a -> IO [a]
putList2Chan -- :: Chan a -> [a] -> IO ()
getChanContents, -- :: Chan a -> IO [a]
writeList2Chan -- :: Chan a -> [a] -> IO ()
) where
import Prelude
import IOBase ( IO(..), ioToST, stToIO ) -- Suspicious!
import ConcBase
import STBase
import Unsafe ( unsafeInterleaveIO )
......@@ -38,7 +37,6 @@ of the channel contents,i.e., the read- and write ends. Empty @MVar@s
are used to handle consumers trying to read from an empty channel.
\begin{code}
data Chan a
= Chan (MVar (Stream a))
(MVar (Stream a))
......@@ -46,8 +44,6 @@ data Chan a
type Stream a = MVar (ChItem a)
data ChItem a = ChItem a (Stream a)
\end{code}
See the Concurrent Haskell paper for a diagram explaining the
......@@ -57,14 +53,12 @@ how the different channel operations proceed.
these two @MVar@s with an empty @MVar@.
\begin{code}
newChan :: IO (Chan a)
newChan
= newEmptyMVar >>= \ hole ->
newMVar hole >>= \ read ->
newMVar hole >>= \ write ->
newChan = do
hole <- newEmptyMVar
read <- newMVar hole
write <- newMVar hole
return (Chan read write)
\end{code}
To put an element on a channel, a new hole at the write end is created.
......@@ -73,55 +67,50 @@ filled in with a new stream element holding the entered value and the
new hole.
\begin{code}
writeChan :: Chan a -> a -> IO ()
writeChan (Chan read write) val
= newEmptyMVar >>= \ new_hole ->
takeMVar write >>= \ old_hole ->
putMVar write new_hole >>
putMVar old_hole (ChItem val new_hole) >>
return ()
writeChan (Chan read write) val = do
new_hole <- newEmptyMVar
old_hole <- takeMVar write
putMVar write new_hole
putMVar old_hole (ChItem val new_hole)
readChan :: Chan a -> IO a
readChan (Chan read write)
= takeMVar read >>= \ rend ->
takeMVar rend >>= \ (ChItem val new_rend) ->
putMVar read new_rend >>
return val
readChan (Chan read write) = do
read_end <- takeMVar read
(ChItem val new_read_end) <- takeMVar read_end
putMVar read new_read_end
return val
dupChan :: Chan a -> IO (Chan a)
dupChan (Chan read write)
= newEmptyMVar >>= \ new_read ->
readMVar write >>= \ hole ->
putMVar new_read hole >>
dupChan (Chan read write) = do
new_read <- newEmptyMVar
hole <- readMVar write
putMVar new_read hole
return (Chan new_read write)
unGetChan :: Chan a -> a -> IO ()
unGetChan (Chan read write) val
= newEmptyMVar >>= \ new_rend ->
takeMVar read >>= \ rend ->
putMVar new_rend (ChItem val rend) >>
putMVar read new_rend >>
return ()
unGetChan (Chan read write) val = do
new_read_end <- newEmptyMVar
read_end <- takeMVar read
putMVar new_read_end (ChItem val read_end)
putMVar read new_read_end
\end{code}
Operators for interfacing with functional streams.
\begin{code}
readChanContents :: Chan a -> IO [a]
readChanContents ch
getChanContents :: Chan a -> IO [a]
getChanContents ch
= unsafeInterleaveIO (do
x <- readChan ch
xs <- readChanContents ch
x <- readChan ch
xs <- getChanContents ch
return (x:xs)
)
-------------
putList2Chan :: Chan a -> [a] -> IO ()
putList2Chan ch ls = sequence (map (writeChan ch) ls)
writeList2Chan :: Chan a -> [a] -> IO ()
writeList2Chan ch ls = sequence (map (writeChan ch) ls)
\end{code}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment