ふつける練習問題を解く:3,4章
レポートのお陰で,活発にHaskellの勉強ができなかった鬱憤を晴らすかのような,一日で三度目のHaskell更新.とは言うものの,記事そのものは一気に書いてますけど.
とりあえずテキスト処理をしなければいけないので,テキストを用意.
RubyPerl RubyPerl JavaC++.NET PythonSmalltalk PythonSmalltalk
3章
大まかな狙いは,「高階関数は素敵だよ」だと思う.
標準入力の'a'と'A'を入れ替える
main = do cs <- getContents putStrLn $ swapa cs swapa [] = [] swapa (c:cs) | c == 'a' = 'A': swapa cs | otherwise = c : swapa cs
次に,高階関数を使って.
main = do cs <- getContents putStrLn $ swapa cs swapa cs = map swap cs swap c = if c == 'a' then 'A' else c
実行結果
$ ./swapa < lang.txt RubyPerl RubyPerl JAvAC++.NET PythonSmAlltAlk PythonSmAlltAlk
追記
ちゃんとしたバージョン.
swapa cs = map swap cs swap 'a' = 'A' swap 'A' = 'a' swap c = c
パターンマッチの方が,if文を使うよりも綺麗に書けて良いかな,と.
4章
大まかな狙いは,「importは便利だよ」だと思う.
標準入力を行単位でソートする
List.sortを使っちゃおう,という問題.
import List main = do cs <- getContents putStrLn $ unlines $ sort $ lines cs
文字列を扱うイディオムとして「unlines $ (何か操作) $ lines cs」みたいに覚えちゃおう,らしい.
実行結果.
$ ./sort < lang.txt JavaC++.NET PythonSmalltalk PythonSmalltalk RubyPerl RubyPerl
同じ行が連続していたら一行にまとめる
List.groupを使っちゃおう,という問題.
import List main = do cs <- getContents putStrLn $ unlines $ map head $ group $ lines cs
実行結果.
$ ./uniq < lang.txt RubyPerl JavaC++.NET PythonSmalltalk
一応チラッと答を見たんだけど,なんかかっこ良かった.
import List main = putStr . unlines . map (head) . group . lines =<< getContents
なるほどなんだが,最後の(=<<)を回答だからと言って,突然披露するのが凄いと思った.