Haskellお勉強会第6日目まとめ
"Real World Haskell"の第4章の5節まで読み終えました。
Real World Haskell―実戦で学ぶ関数型言語プログラミング
- 作者: Bryan O'Sullivan,John Goerzen,Don Stewart,山下伸夫,伊東勝利,株式会社タイムインターメディア
- 出版社/メーカー: オライリージャパン
- 発売日: 2009/10/26
- メディア: 大型本
- 購入: 8人 クリック: 245回
- この商品を含むブログ (76件) を見る
Real World Haskell 第4章の読書メモ
- 外部とのやり取りを行う場合はdo記法による「アクション」を使うんだ。
- 「<-」はdoブロックの中での代入みたいなもんだ。微妙に違うが最初は気にすんな
- break 関数は最初にfalseを受け取った時点で終了するぞ
- OSの違いによる改行コードの違いには気をつけよう
- python の改行は良く出来ている!
- デカいコードをいきなり書くとテストしにくいから小さいところから始めよう!結果として読みやすいコードになるぞ!
- 関数をバッククォートで囲むと中置関数として使えるぞ!読みやすくなったりするけど適切に使おう
- length関数は線形時間がかかるぞ!空リストの判定にはnull関数を使おう! パターンマッチも役立つぞ!
- Boolのリストにはand, or関数とかもあるぞ!地味に便利
- all, anyもよろしくな!
ここが気になる
- break 関数みたいな(a -> Bool) -> [a] -> ([a], [a])でリストの最後まで走査する関数は何じゃろ? -> partitionだよ
- spanとpartitionが紛らわしいわ
練習問題
- 1 head, tailなどの関数の「安全版」を作れ
safeHead [] = Nothing safeHead xs = Just(head(xs))
以下略
- 2 述語をと任意の方のリストを取り、述語がFalseを返す要素で入力リストを分割するsplitWidthxを作れ
splitWith :: (a -> Bool) -> [a] -> [[a]] splitWith _ [] = [] splitWith pred xs = let (pre, suf) = span pred xs in pre : case suf of [] -> [] _ -> splitWith pred (tail suf)
> splitWith even [1,1,1,2,3,3,3,4,5] [[],[],[],[2],[],[],[4]]
みたいなキモい事になったので、
splitWith :: (a -> Bool) -> [a] -> [[a]] splitWith _ [] = [] splitWith pred xs = let (_, dropped) = break pred xs in let (pre, suf) = span pred dropped in pre : splitWith pred suf
と変えたら
> splitWith even [1,1,1,2,3,3,3,4,5] [[2],[4][]]
みたいになってしまったでござる。
splitWith :: (a -> Bool) -> [a] -> [[a]] splitWith _ [] = [] splitWith pred xs = let (_, dropped) = break pred xs in case dropped of [] -> [] _ -> let (pre, suf) = span pred dropped in pre : splitWith pred suf
- 3 入力各行の最初の単語を印字するプログラムを作れ
interactWith function inputfile outputfile = do input <- readFile inputfile writeFile outputfile (function input) main = mainWith myFunction where mainWith function = do args <- getArgs case args of [input, output] -> interactWith function input output _ -> putStrLn "error" myFunction x = let line = lines x in firstWords line firstWords line = case line of [] -> [] _ -> firstWord (head line) ++ ['\n'] ++ firstWords (tail line) firstWord l = case l of [] -> [] _ -> head (splitWith isChar l) isChar c = c /= ' '