我用了 Haskell 小小的實做了 Unix 的 cat 指令
算是第一個有點用處的 Haskell 程式
代碼如下
{-
Haskell implementation of cat(1)
Copyright (c) Allen Lin, 2006.
-}
module Cat (catFile) where
import IO
import Text.Printf
data CatOpts = NeedReverse
| NeedLine
| NeedTab
| NeedEOL deriving Eq
catFile :: FilePath -> [CatOpts] -> IO ()
catFile fp opts = do
h <- openFile fp ReadMode
catContent h opts 1
hClose h
catContent :: Handle -> [CatOpts] -> Int -> IO ()
catContent h opts line = do
eof <- hIsEOF h
if eof then do
putNewLine
return ()
else do
content <- hGetLine h
putLineNumber line (NeedLine `elem` opts)
let content' = content ++ "\n" in mapM_ (\x -> catContent2 x opts) content'
catContent h opts line'
where line' = incDecNum True line
catContent2 :: Char -> [CatOpts] -> IO ()
catContent2 c opts =
if is_needeol && c == '\n'
then do putStrLn "$"
else
if is_needtab && c == '\t'
then do putStr "^I"
else do putChar c
where is_needtab = NeedTab `elem` opts
is_needeol = NeedEOL `elem` opts
putNewLine :: IO ()
putNewLine = putStrLn ""
putLineNumber :: Int -> Bool -> IO ()
putLineNumber n b =
case b of
True -> do putStr $ printf "%5d " n
_ -> do return ()
incDecNum :: Bool -> Int -> Int
incDecNum b n =
case b of
True -> n + 1
otherwise -> n - 1