--
import IO import Concurrent {- openFile :: FilePath -> IOMode -> IO Handle hClose :: Handle -> IO () data IOMode = ReadMode | WriteMode | AppendMode deriving (Eq, Ord, Ix, Bounded, Enum, Read, Show) -- When in WriteMode hPutChar :: Handle -> Char -> IO () hPutStr :: Handle -> String -> IO () hPutStrLn :: Handle -> String -> IO () hPrint :: Show a => Handle -> a -> IO () -- When in ReadMode hGetChar :: Handle -> IO Char hGetLine :: Handle -> IO String -- Entire Contents returned as String hGetContents :: Handle -> IO String -- Why use Handle's when we have functions like: writeFile :: FilePath -> String -> IO () appendFile :: FilePath -> String -> IO () -- Predefined standard Channels stdin, stdout, stderr :: Handle -- Error Handling while doing IO isEOFError :: IOError -> Bool ioError :: IOError -> IO a -- Raise an IOError catch :: IO a -> (IOError -> IO a) -> IO a -} getChar' :: IO Char getChar' = catch getChar (\ e -> return '\n') getChar2 :: IO Char getChar2 = catch getChar (\ e -> if isEOFError e then return '\n' else ioError e) getLine' :: IO String getLine' = catch getLine'' (\ e -> return ("Error: " ++ show e)) where getLine'' = do { c <- getChar2 ; if c == '\n' then return "" else do { l <- getLine' ; return (c:l) } } getAndOpenFile :: String -> IOMode -> IO Handle getAndOpenFile prompt mode = do { putStr prompt ; name <- getLine ; catch (openFile name mode) (\e -> do { putStrLn ("Cannot open: "++name) ; print e ; 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 ; putStr "Done\n" } -- First Class Channels {- -- First Class Channel Operations newChan :: IO (Chan a) writeChan :: Chan a -> a -> IO () readChan :: Chan a -> IO a getChanContents :: Chan a -> IO [a] isEmptyChan :: Chan a -> IO Bool -} ex1 = do { c <- newChan ; writeChan c 'a' ; writeChan c 'b' ; a <- readChan c ; b <- readChan c ; print [a,b] ; return [a,b] } -- forkIO :: IO () -> IO () ex2 :: IO() ex2 = 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 } --