#"Real World Haskell" 読書会会場にゃう♩☆ミ 例によって、実況は Chaton で行ないます。
#p.395 最後が行終端文字になっていないファイルは、Unix ではテキストファイルじゃない。
#メールなら大丈夫だよ。
#SMTP 的には最後に CRLF がつく事を要求。なので、終端文字がついていないと、CRLF が勝手について署名がダメになってしまうことが。
#CSV の RFC 的には、CRLF がつかなくても良い。
#GHC は、Haskell ソースコードの最後に行終端文字がついてないと警告メッセージを出すよね。
#というあたりでしたっけ?(間違っていたら、修正お願いします。)
#"この現象は、入力ファイルが CRLF で終わっているときに起きる。理由は、field の定義が空文字を許すので、最後の CRLF で終わりなのか、次の行があるのか判断できないためだ。
とういう訳で、RFC4180 の BNF の定義は、間違っているとは言えないものの、曖昧であることが分かる。"
##より。
#RFC の ABNF はきちんと検証されていない。今は Parsec とかがあるので、検証しようと思えばできるはずだけど。
#(C++ でも Boost.Spirit とか)
#再開前にあった議論。
#Haskell 2010 及び GHC 7.0.1 には DoAndIfThenElse という機能が入った。
###GHC Current (HEAD) では Haskell 標準的には間違っているけれど GHC では許されていたようなインデントを、NondecreasingIndentation という拡張機能にした。
###GHC Current ではもう一つ、{} が入る場合の Haskell 標準的には間違っていたインデントも RelaxedLayout という拡張機能にしている。
####あと、GHC のバグを直すために入った FlexibleInstances や BangPatterns に対する変更で、後方互換性が崩れて色々とギャーな感じに。 http://www.haskell.org/pipermail/glasgow-haskell-users/2011-January/019873.html #network パッケージでこれらの変更に引っかかって色々と苦労した。
##GHC 7.0.1 では、将来の Haskell 標準に入るかもしれない非互換な変更がもう一つありますね。
#「let 式や where 節などで定義するローカルな変数束縛(関数定義)に型シグネチャがない場合、型を勝手に多相的には推論しないようにする(単相的に推論する)」MonoLocalBinds という拡張機能が入っている。
###MonoLocalBinds が有効な場合、型を多相的に推論させるためには必ず型シグネチャをつけなければならない。 (foo = id みたいな定義でも、型シグネチャがない限り単相的に扱おうとする。)
#GADTs や TypeFamiles を使う場合、MonoLocalBinds は勝手に有効になる。
#MonoLocalBinds は元々 GADTs (や TypeFamilies の)型推論をうまくいくようにする(そしてもっと堅牢な実装にする)ための仕組みなため。
####TypeFamilies の motivation って?
##関数従属は関係的、もっと(型)関数的に書きたい。
##関数従属は GADTs と一緒に使えないので、GADTs と自然に連携できる機能が欲しかった。将来的には関数従属を型族(Type Families)の syntax sugar とすることを考えている。
##(そこから派生して)別 branch で開発中の、データ型や関数を型レベルに持ち上げる機能の話。
###……というわけで、無駄にこの辺の話をまとめておきました。
#Web テストの話。
##……どうやら違ったみたいです。このパッケージは知らなかったとのこと。
#pappy はパッケージングミスしている!
#Main パッケージから import されているファイルが、pappy の tar.gz に入っていない。
#s/Main パッケージ/Main モジュール/
#Cabal の Home page フィールドに載っている URL には、Main が import しようとしているモジュール(ファイル)を置いてあるので、これはパッケージ化した人の単純ミス。
##簡単なものをパースするなら、Parsec 使うよりも base パッケージの Text.ParserCombinators.ReadP を使ったら?
#ただし、Text.ParserCombinators.ReadP はかなり富豪的。
#この流れから↑にある Packrat Parser の話になりました。
#Text.ParserCombinators.ReadP にある単純な Parser Combinator のメモリリークの問題。それを解決したのが Parsec。
#でも、Parser Combinator を使おうとしている人は、メモリリークの問題のところで Haskell は使えないという結論を出してしまう。Parsec のものは問題を解決しているのにね。
#ちなみに Text.ParserCombinators.ReadP で Read を書くのは難しいという考えからできたのが、polyparse http://hackage.haskell.org/package/polyparse ###正規表現ライブラリは何がお薦め?
#regex-posix を使っている人は regex-tdfa に乗り換えるべき!
#regex-tdfa は regex-posix を置き換えるのを目的に作られたライブラリ。
#regex.h 由来のバグがなくて、速くて、Lazy にも使える。
#regex-tdfa の作者は早く、Haskell Platform に regex-posix を regex-tdfa に置き換える Proposal を提出するべき。
#(ただし、regex-tdfa で対応しているのは POSIX 正規表現のみ。)
#Perl 正規表現使いたい人は何使うべき?
##regex-pcre が良いんじゃない? Perl のライブラリを使っているから速度は Perl と一緒って言えるし。
#ただし、使用する pcre ライブラリに注意。
#Haskell Platform で提供されている Mac OS X 版バイナリは 32 bit なのに対し、Mac OS X のライブラリは 64 bit。
#Mac Ports で +universal を指定していれれば、pcre の 32 bit バイナリも 64 bit バイナリも両方入る。
#MacPorts では GHC の 64 bit 版バイナリが作れるよ。 (ただし、バージョンは 6.10.4 と古いけれど。)http://hackage.haskell.org/trac/ghc/ticket/2965#comment:74 #GHC 7.0.1 には(上記のバイナリを利用して作った)64 bit 版バイナリが提供されている。(ただし、./configure & make install でインストール) http://www.haskell.org/ghc/download_ghc_7_0_1#macosx_x86_64 #GHC 7.0.2 では GUI インストーラー付きの Mac OS X 64 bit 版バイナリが提供される予定。
###ただし、型検査器まわりを直しているので、少々時間がかかるけれど。
###全然関係ない Scala の話が出てくるのはなぜ? Plugin で拡張可能な数少ない言語処理系の一つだから。
#今のところ、Plugin で拡張可能なのは GCC、LLVM、Scala ぐらい。
#GCC plugin は、GCC のソースコードに直接手を入れずにバックエンドや最適化パスの追加などができる機能。 http://blog.kmckk.com/archives/2490156.html #GHC Plugin でも同じようなことができるようにするのを目的としている。
#現在のところ、GHC Plugin の patch で拡張可能なのは GHC Core → GHC Core の最適化のみですが。
#上にリンクした予定には、(Hoopl を使った)C-- → C-- の最適化パスの追加やバックエンドの追加などを可能にする機能も提案されています。
#lambda lifting と lambda hoisting の違いは?
##p.406 現在の Parsec3 では Applicative クラスや Alternative クラスのインスタンスになっている。
##ただし、
#type GenParser tok st = Parsec [tok] st
type Parsec s u = ParsecT s u Identity
##parsec3 パッケージも同様。
###GHCに -fno-full-laziness を指定しない限り、局所的な定義は自動的にトップレベルに持ち上げられるはず。
###↑ -fno-full-lazines の参考リソース
#s/-fno-full-lazines/-fno-full-laziness/
#expr = term `chainl1` addop
term = factor `chainl1` mulop
factor = parens expr <|> integer
mulop = do{ symbol "*"; return (*) }
<|> do{ symbol "/"; return (div) }
addop = do{ symbol "+"; return (+) }
<|> do{ symbol "-"; return (-) }
#p.410 Numeric モジュールの readFloat を使っているのは狡い。
#使わないと中身についての細かな説明が必要。
#readFloat を使っているのは "Real World" Haskell だし、実際にはこう書くという例が重要だから。
#Applicative を積極的に使っていないのは?
#Real World Haskell を書いていた GHC 6.8.x の時点では、まだ Applicative が入ってからあんまり経っていない。
##(多分)この章を書いた Bryan はこの当時 Applicative にあんまり慣れてなくて、彼の blog では The Typeclassopedia の著者の Brent Yorgey から Applicative 使えとつっこまれている。
#あっ、blog ではなく "Real World Haskell" の Draft の方かも。(聞き書き + 記憶の掘り起こしなので、曖昧です。)
#その後、Applicative を使うよう Real World Haskell の原稿を修正したものの、修正が間に合わなかった部分があるのだろう。
#(前にもたびたび同じような話題が上がってましたが、メモってなかったので、念のため。)
#ブログです。
##正しくは、Bryan liftA3 foo bar baz goo と書いていたのですが、Yorgey に foo <$> bar <*> baz <*> goo と書けるよと教えてもらったのです。
#ああ、なるほど。それで liftA を使っているけれど……という話が出てきたんですね。
#情報ありがとうございます。
#p.414 ここで System.Timeout が出てくるのか。
##System.Timeout と ** の相性
#timeout と System.Process の waitForProcess
#waitForProcess は中で FFI から呼ばれる関数を使って処理をブロックしているので、GHC 7.0x までは waitForProcess の処理が完全にブロックされてしまう。
#timeout のドキュメントに FFI を使っているとダメだよと書いてあるので、そこを見て waitForProcess のコードを見れば……
#waitForProcess は単なる c_waitForProcess 呼び出しではないので、ドキュメント見ても直ぐには理解的ないかも。
##GHC Current では interruptible FFI Call というのが入って、waitForProcess を中断可能になった。
####ただし、Windows の場合には Windows Vista 以降に限る。
#Windows では interruptible FFI Call の実装に、Vista 以降で追加された CancelSynchronousIo という API を使っているため。
##timeout と getContents の相性
##System.Timeout の実装は forkIO 使っている。
###第16章終了。次回は『第17章 Cとのインタフェース:FFI』からですね。
#ちなみに、Asynchronous Exceptions in Haskell という論文に載っていた timeout の実装はカッコ良かったです。 http://bit.ly/eL0qqx #次回の日程は今のところ未定。後で確認。
#カッコ良くはないですけれど、"Tackling the awkward squad" にも timeout の実装はありますね。 http://j.mp/dG0AWM #そうやって色々と出ていた timeout の実装が、Haskell コミュニティにとってようやく満足できる形になったのが、GHC 6.8.1 の頃です。 http://j.mp/iei6q6 #飲み会で話題になった配列の再作成のコストを削減する話については、手前味噌ですが連載の第42回で書いたのでリンクを張っておきます。 http://itpro.nikkeibp.co.jp/article/COLUMN/20101013/352848/