This code was automatically extracted from a .lhs file that uses the following convention: -- lines beginning with ">" are executable -- lines beginning with "<" are in the text, but not necessarily executable -- lines beginning with "|" are also in the text, but are often just expressions or code fragments. < openFile :: FilePath -> IOMode -> IO Handle < hClose :: Handle -> IO () < data IOMode = ReadMode | WriteMode < | AppendMode | ReadWriteMode < hPutChar :: Handle -> Char -> IO () < hPutStr :: Handle -> String -> IO () < hPutStrLn :: Handle -> String -> IO () < hPrint :: Show a => Handle -> a -> IO () < hGetChar :: Handle -> IO Char < hGetLine :: Handle -> IO String < hGetContents :: Handle -> String < writeFile :: FilePath -> String -> IO () < type FilePath = String < appendFile :: FilePath -> String -> IO () < getChar = hGetChar stdin < putChar = hPutChar stdout < isEOFError :: IOError -> Bool < catch :: IO a -> (IOError -> IO a) -> IO a < getChar' :: IO Char < getChar' = catch getChar (\e -> return '\n') < getChar' :: IO Char < getChar' = catch getChar (\e -> if isEOFError e then return '\n' < else ioError e) < getLine':: IO String < getLine' = catch getLine'' (\err -> "Error: " ++ show err) < where getLine'' = do c <- getChar' < if c == '\n' then return "" < else do l <- getLine' < return (c:l) > module Main where > import IO > > getAndOpenFile :: String -> IOMode -> IO Handle > getAndOpenFile prompt mode > = do putStr prompt > name <- getLine > catch (do handle <- openFile name mode > return handle) > (\error -> do putStrLn ("Cannot open " ++ name) > print error > getAndOpenFile prompt mode) > > main = do fromHandle <- getAndOpenFile "Copy from: " ReadMode > toHandle <- getAndOpenFile "Copy to: " WriteMode > contents <- hGetContents fromHandle > hPutStr toHandle contents > hClose fromHandle > hClose toHandle > putStrLn "Done." < newChan :: IO (Chan a) < writeChan :: Chan a -> a -> IO () < readChan :: Chan a -> IO a < getChanContents :: Chan a -> IO [a] < isEmptyChan :: Chan a -> IO Bool < do c <- newChan < writeChan c `a` < writeChan c `b` < ... < do ... < a <- readChan c < b <- readChan c < return [a,b] < forkIO :: IO () -> IO () > module ChannelTest where > > import Channel > import ConcBase > > main :: IO () > main = do c1 <- newChan :: IO (Chan Int) > c2 <- newChan :: IO (Chan Int) > forkIO (client c1 c2) > forkIO (server c2 c1) > > client :: Chan Int -> Chan Int -> IO () > client cin cout > = do writeChan cout 1 > loop > where loop = do c <- readChan cin > print c > writeChan cout c > loop > > server :: Chan Int -> Chan Int -> IO () > server cin cout > = do loop > where loop = do c <- readChan cin > writeChan cout (c+1) > loop