hnakamur’s blog

ものすごい勢いで忘れる私のために未整理でもいいからとりあえずメモ

2011-07-02

Haskellで行番号付きcatのサンプル

Amazon.co.jp: ふつうのHaskellプログラミング ふつうのプログラマのための関数型言語入門: 青木 峰郎, 山下 伸夫: 本のコードを少しだけ改良。行番号の桁数を6桁固定ではなく計算で求めるようにしてみました。

main = do cs <- getContents
          putStr $ numbering cs
  where
    numbering :: String -> String
    numbering cs = unlines $
        map (format $ nwidth $ length $ lines cs) (zipLineNumber $ lines cs)

    zipLineNumber :: [String] -> [(Int, String)]
    zipLineNumber xs = zip [1..] xs

    nwidth :: Int -> Int
    nwidth len = ceiling $ logBase 10 $ fromIntegral $ len + 1

    format :: Int -> (Int, String) -> String
    format width (n, line) = rjust width (show n) ++ "  " ++ line

    rjust :: Int -> String -> String
    rjust width s = replicate (width - length s) ' ' ++ s

ポイントフリースタイルにして、さらにdoを(>>=)で書き換えた版です。numberingのシグネチャも変えました。
main = getContents >>= putStr . unlines . numbering . lines
  where
    numbering :: [String] -> [String]
    numbering ls = map (format $ nwidth $ length ls) (zipLineNumber ls)

    zipLineNumber :: [String] -> [(Int, String)]
    zipLineNumber = zip [1..]

    nwidth :: Int -> Int
    nwidth = ceiling . logBase 10 . fromIntegral . (1 +)

    format :: Int -> (Int, String) -> String
    format width (n, line) = rjust width (show n) ++ "  " ++ line

    rjust :: Int -> String -> String
    rjust width s = replicate (width - length s) ' ' ++ s

ブログ アーカイブ