ふつけ-る(ラ行五段活用)

「Real World Haskell」がいまいち頭に入らなかったので、「ふつうのHaskellプログラミング」で修行中。今第7章(基本的な構文)まで行った。

Real World Haskell―実戦で学ぶ関数型言語プログラミング ふつうのHaskellプログラミング ふつうのプログラマのための関数型言語入門

演習問題を順調に片付けていく。そして第7章演習。

  • 標準入力から読んだ各行を幅60byteになるよう折り返すコマンドfoldを書け
  • 単語境界とかマルチバイト文字は気にしなくていいよ
  • splitAt関数が役立つよ

実際は↑のようなくだけた文ではないです。

んで、7章の内容とにらめっこしてできたのがこれ。

main = do cs <- getContents
          putStr $ unlines $ fold $ lines cs

fold :: [String] -> [String]
fold [] = []
fold (x:xs) = fold' (splitAt 60 x) ++ fold xs
     where
        fold' (_fst, _snd) = if (null _snd) then [_fst]
                                            else [_fst, _snd]

模範解答( http://i.loveruby.net/ja/stdhaskell/samples/fold.hs.html )はこれ。

foldWidth = 60

main = do cs <- getContents
          putStr $ fold cs

fold cs = unlines $ concatMap foldLine $ lines cs

foldLine line = case splitAt foldWidth line of
                  (s, [])   -> [s]
                  (s, cont) -> s : foldLine cont

うーん、だいぶ違うもんだなあ。
いまいち思いつかなかったんで++で連結したが、[[a]] -> [a]の処理を行うにはconcat(又はconcatMap)が役立つと覚えておこう。こっちの方が実行効率よさそうだし。あとcase文も記憶の片隅に。