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} \section[Channel]{Unbounded Channels}
...@@ -21,13 +21,12 @@ module Channel ...@@ -21,13 +21,12 @@ module Channel
unGetChan, -- :: Chan a -> a -> IO () unGetChan, -- :: Chan a -> a -> IO ()
{- stream interface -} {- stream interface -}
readChanContents, -- :: Chan a -> IO [a] getChanContents, -- :: Chan a -> IO [a]
putList2Chan -- :: Chan a -> [a] -> IO () writeList2Chan -- :: Chan a -> [a] -> IO ()
) where ) where
import Prelude import Prelude
import IOBase ( IO(..), ioToST, stToIO ) -- Suspicious!
import ConcBase import ConcBase
import STBase import STBase
import Unsafe ( unsafeInterleaveIO ) import Unsafe ( unsafeInterleaveIO )
...@@ -38,7 +37,6 @@ of the channel contents,i.e., the read- and write ends. Empty @MVar@s ...@@ -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. are used to handle consumers trying to read from an empty channel.
\begin{code} \begin{code}
data Chan a data Chan a
= Chan (MVar (Stream a)) = Chan (MVar (Stream a))
(MVar (Stream a)) (MVar (Stream a))
...@@ -46,8 +44,6 @@ data Chan a ...@@ -46,8 +44,6 @@ data Chan a
type Stream a = MVar (ChItem a) type Stream a = MVar (ChItem a)
data ChItem a = ChItem a (Stream a) data ChItem a = ChItem a (Stream a)
\end{code} \end{code}
See the Concurrent Haskell paper for a diagram explaining the See the Concurrent Haskell paper for a diagram explaining the
...@@ -57,14 +53,12 @@ how the different channel operations proceed. ...@@ -57,14 +53,12 @@ how the different channel operations proceed.
these two @MVar@s with an empty @MVar@. these two @MVar@s with an empty @MVar@.
\begin{code} \begin{code}
newChan :: IO (Chan a) newChan :: IO (Chan a)
newChan newChan = do
= newEmptyMVar >>= \ hole -> hole <- newEmptyMVar
newMVar hole >>= \ read -> read <- newMVar hole
newMVar hole >>= \ write -> write <- newMVar hole
return (Chan read write) return (Chan read write)
\end{code} \end{code}
To put an element on a channel, a new hole at the write end is created. 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 ...@@ -73,55 +67,50 @@ filled in with a new stream element holding the entered value and the
new hole. new hole.
\begin{code} \begin{code}
writeChan :: Chan a -> a -> IO () writeChan :: Chan a -> a -> IO ()
writeChan (Chan read write) val writeChan (Chan read write) val = do
= newEmptyMVar >>= \ new_hole -> new_hole <- newEmptyMVar
takeMVar write >>= \ old_hole -> old_hole <- takeMVar write
putMVar write new_hole >> putMVar write new_hole
putMVar old_hole (ChItem val new_hole) >> putMVar old_hole (ChItem val new_hole)
return ()
readChan :: Chan a -> IO a readChan :: Chan a -> IO a
readChan (Chan read write) readChan (Chan read write) = do
= takeMVar read >>= \ rend -> read_end <- takeMVar read
takeMVar rend >>= \ (ChItem val new_rend) -> (ChItem val new_read_end) <- takeMVar read_end
putMVar read new_rend >> putMVar read new_read_end
return val return val
dupChan :: Chan a -> IO (Chan a) dupChan :: Chan a -> IO (Chan a)
dupChan (Chan read write) dupChan (Chan read write) = do
= newEmptyMVar >>= \ new_read -> new_read <- newEmptyMVar
readMVar write >>= \ hole -> hole <- readMVar write
putMVar new_read hole >> putMVar new_read hole
return (Chan new_read write) return (Chan new_read write)
unGetChan :: Chan a -> a -> IO () unGetChan :: Chan a -> a -> IO ()
unGetChan (Chan read write) val unGetChan (Chan read write) val = do
= newEmptyMVar >>= \ new_rend -> new_read_end <- newEmptyMVar
takeMVar read >>= \ rend -> read_end <- takeMVar read
putMVar new_rend (ChItem val rend) >> putMVar new_read_end (ChItem val read_end)
putMVar read new_rend >> putMVar read new_read_end
return ()
\end{code} \end{code}
Operators for interfacing with functional streams. Operators for interfacing with functional streams.
\begin{code} \begin{code}
getChanContents :: Chan a -> IO [a]
readChanContents :: Chan a -> IO [a] getChanContents ch
readChanContents ch
= unsafeInterleaveIO (do = unsafeInterleaveIO (do
x <- readChan ch x <- readChan ch
xs <- readChanContents ch xs <- getChanContents ch
return (x:xs) return (x:xs)
) )
------------- -------------
putList2Chan :: Chan a -> [a] -> IO () writeList2Chan :: Chan a -> [a] -> IO ()
putList2Chan ch ls = sequence (map (writeChan ch) ls) writeList2Chan ch ls = sequence (map (writeChan ch) ls)
\end{code} \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