--
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
}
--