すごいH本4

9章まで読んだ。全然進んでない…9月までに終わりたかった…

読んでてへぇとなったとことか疑問に思ったとこのメモ…というほど読めてもないのでただの感想。
・doブロック内の<-をみてて、リスト内包表記の<-は∈由来らしいって前見たけど、リストも値を[]に入れてる箱っぽいし、<-はなんか箱に入ってる値を取り出す記号と見るのがよさそう(こういうたとえ話を書くとかしこい人が怒るらしいけどこの本にもそう書いてたしセーフ)。
・case式の->はなんかすっきりとした説明ないんかな?
・mainを再帰的にして終わらなくしたコード

main = do
    line <- getLine
    if null line
        then do
            main
        else do
            putStrLn $ reverseWords line
            main

の型を調べると

main :: IO b

だった。lineがnullのときに終了するようにしたらmain :: IO ()だったけど、どういう違いがあるんかな。
・ダブルコーテーションが表示されるのださいし文字列かどうかでprintとputStrLnを場合分けってできないんかな。型で場合分けするのってありそうなのに出てきてないってことはないんかな。
・遅延IOがさっぱりイメージできない。大量の入力がきて、それが使われないときはメモリからあふれたりしないの?
・getContentsやinteractはCtrl+Zがくるまで終了しないって感じなのかな。そういや上の無限ループのやつはCtrl+Zを入れると

*** Exception: <stdin>: hGetLine: end of file

って(異常)終了するし、これが場合分けに入ってるとか?
最初これがわかってなくてCtrl+Cで無理やり終了させてたけどそうするとGHCiやMSYSもわけわからんことになってとても困ってた。
それでも例えば

main :: IO ()
main = interact reverseWords

をCtrl+Zで終了させるととりあえず無事に終了するけど、そのままGHCiを閉じないで:rしたら

*** Exception: <stdin>: hGetContents: illegal operation (handle is closed)

と出てロードできなくなった。System.IO.stdinが閉じてしまったってことだと思うけど、openFileしようにもFilePathがわからない。
もうIOのあるやつはGHCiでロードするのではなくてコンパイルして動かすのがよさそう。
コンパイル時の中間ファイルを出さないghcのオプションらしい-no-keep-hi-files/-no-keep-o-filesがhelpにも見つからないけど無くなった?
・GHCiでロードしたプログラム名をgetProgNameで取得すると<interactive>だった。
・本のToDoリストについて、エラー処理が練習問題となっていたので考えてみた。
まず引数がない時の問題について、

(command:argList) <- getArgs -- 引数がないとき[]が返るのでパターンマッチに失敗する

のでパターンマッチの前にif式で場合分けを入れた。
readFileでそのファイルがなかった時の処理は、

puterror :: SomeException -> IO ()
puterror _ = putStrLn "Error"

みたいな雑なエラー処理の関数つくって、

view :: [String] -> IO ()
view [fileName] = (do
    contents <- readFile fileName
    let 
-- contentsを用いてputStrLnとか適当な処理
    ) `catch` puterror

としてみた。catchのあと直接

\e = putStrLn "Error"

って書けるかなって思ったけどだめだった。ネットで検索したらeの型がうんぬんって書いてた(気がする)し無理なのか…
・上のを考えてた過程で思ったけどbracketやwithFileの例外ってファイルのリソース確保は成功する前提で、処理中に例外発生してもちゃんと開放する関数っぽいな。
・System.Random.StdGenの値をshowしたときの2つの整数は何?
・GHCi上でData.ByteString.pack [65,66,67]を入力すると"ABC"が出てくるので

-- 両方とも怒られる。
Data.ByteString.unpack "ABC"
map Data.Char.ord Data.ByteString.pack [65,66,67]

とやってみたけどだめだった。別にByteStringは文字列の代わりになるわけじゃない?

11章からいよいよかっこいい用語が飛び出してきそうなので10章はさくっとやっていきたい。けどこういう応用例みたいなのってそのままコピペしても面白くないからなんか改造したいけど思いつかなくてなかなか進めないのよね…