tailの実装
Posted feedbacks - Haskell
とりあえず実装してみたというレベル Data.Sequenceを使ってみた 効率については考えてない orz
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | module Main where
import Control.Concurrent
import Data.Foldable
import Data.Sequence
import Prelude hiding (foldl,concat,mapM_)
import System.Console.GetOpt
import System.Environment
import System.IO
data Options = Options
{ optFollowed :: Bool
, optNumber :: Int
} deriving Show
defaultOptions = Options
{ optFollowed = False
, optNumber = 10
}
options :: [OptDescr (Options -> Options)]
options
= [ Option ['f'] [] (NoArg (\ opts -> opts { optFollowed = True }))
"followed by addition to the file"
, Option ['n'] [] (ReqArg (\ d opts -> opts { optNumber = read d }) "NUMBER")
"display last NUMBER lines"]
compileOpts :: [String] -> IO (Options, [String])
compileOpts argv
= case getOpt Permute options argv of
(o,n,[] ) -> return (foldl (flip id) defaultOptions o, n)
(_,_,errs) -> ioError (userError (concat errs ++ usageInfo header options))
where header = "Usage : tail [OPTION..] file"
main :: IO ()
main = getArgs >>= compileOpts >>= tail'
tail' :: (Options, [String]) -> IO ()
tail' (o,fs) = openFile (head fs) ReadMode
>>= loop empty (optNumber o) 0 (optFollowed o)
loop :: Seq String -> Int -> Int -> Bool -> Handle -> IO ()
loop q n i f h
= do { eof <- hIsEOF h
; if eof then if not f then printQ q
else printQ q >> lineCat h
else do { l <- hGetLine h
; if n > i then loop (q |> l) n (i+1) f h
else case viewl q of
_ :< qs -> loop (qs |> l) n n f h
}
}
printQ :: Seq String -> IO ()
printQ = mapM_ putStrLn
lineCat :: Handle -> IO ()
lineCat h = do { eof <- hIsEOF h
; if eof then threadDelay (10^4) >> lineCat h
else hGetLine h >>= putStrLn >> lineCat h
}
|


takeru #6818() Rating-9/11=-0.82
'tail'を実装してください。
巨大なファイルでも効率的に動作するようにしてください。
最低限必要な機能は、
です。
[ reply ]