[過去ログ]
関数型プログラミング言語Haskell Part7 (1001レス)
関数型プログラミング言語Haskell Part7 http://echo.5ch.net/test/read.cgi/tech/1174211797/
上
下
前次
1-
新
通常表示
512バイト分割
レス栞
抽出解除
レス栞
このスレッドは過去ログ倉庫に格納されています。
次スレ検索
歴削→次スレ
栞削→次スレ
過去ログメニュー
リロード規制
です。10分ほどで解除するので、
他のブラウザ
へ避難してください。
897: デフォルトの名無しさん [sage] 2007/09/21(金) 21:07:44 >>895 それで合ってる。seqを中置で使うのは良く見かける気がする。 seqを使っているのは再帰に入る前にelts_lt_xとelts_greq_xを完全に評価するため。 未評価のelts_greq_xのサンクはxsを参照しているけど、 完全に評価してしまえばただのリストなので、xsへの参照がなくなって、 GCがxsを回収できるようになる。 seq A Bの値はBと同じだけど、この式を評価する時はまずAを評価して、 その結果を捨て、改めてBを評価する。 length elts_lt_x `seq` 本体 を評価するときは、まずelts_lt_xの長さを求めることになるが、 リストの長さを求めるにはリスト全体を評価する必要がある。 結局、本体が評価される前にelts_lt_xが完全に評価される。 lengthが必要な理由には、seqの仕様が関わってくる。 seq A Bが評価されるとき、Aは弱冠頭正規形(weak head normal form, WHNF)まで簡約される。 WHNFというのは、最も外側のデータ構築子が確定した形。 例えば1+2や[1,2]++[3,4]はWHNFじゃないけど、3や1:([2]++[3,4])はWHNF。 だから、lengthを使わずに elts_lt_x `seq` 本体 のように定義すると、例えば elts_lt_x = [y | y <- [1, 2, 3, 4], y < 5] のとき、これを elts_lt_x = 1 : [y | y <- [2, 3, 4], y < 5] と簡約したら、この段階でWHNFに達したことになり、評価が終わってしまう。 これだと、xs(ここでは[2, 3, 4])への参照が残っていて、GCがxsを回収できない。 http://echo.5ch.net/test/read.cgi/tech/1174211797/897
901: デフォルトの名無しさん [sage] 2007/09/21(金) 22:02:09 >>897 力作ありがとうございます。 seqは完全に遅延評価を回避できるわけではないんですね。なんというか、オブジェクト指向言語でよく出てくるshallow copyとdeep copyの違いみたいな感じでしょうか(つまりseqはshallow copyに似ている)。 しかし完全に評価するためにlengthを使うのって、bad know howですよね。 このためにlengthを使うのは、lengthの本来の用途ではないのだから、完全に評価するための専用の関数が標準で用意されるべきたと思いました。たとえその実体がlengthであったとしても。 http://echo.5ch.net/test/read.cgi/tech/1174211797/901
メモ帳
(0/65535文字)
上
下
前次
1-
新
書
関
写
板
覧
索
設
栞
歴
スレ情報
赤レス抽出
画像レス抽出
歴の未読スレ
AAサムネイル
Google検索
Wikipedia
ぬこの手
ぬこTOP
0.037s