我的第一次

我用了 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

發表迴響

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 變更 )

Twitter picture

You are commenting using your Twitter account. Log Out / 變更 )

Facebook照片

You are commenting using your Facebook account. Log Out / 變更 )

連結到 %s


Follow

Get every new post delivered to your Inbox.