challenge tailの実装

'tail'を実装してください。

巨大なファイルでも効率的に動作するようにしてください。

最低限必要な機能は、

  • 行数指定
  • 「-f」パラメータの対応

です。

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
               }

Index

Feed

Other

Link

Pathtraq

loading...