関数型プログラミング言語Haskell Part34 (684レス)
上下前次1-新
抽出解除 必死チェッカー(本家) (べ) 自ID レス栞 あぼーん
リロード規制です。10分ほどで解除するので、他のブラウザへ避難してください。
47: デフォルトの名無しさん [] 2022/01/16(日) 12:22:44.80 ID:f2QwXzzi(1/4) AAS
質問です
何かの文章で
square x = x*x
print $ square $ square 3
のようなプログラムをHaskell は
square $ square 3
→ square ( square 3 )
→ ( square 3 ) * ( square 3 )
→ ( 3 * 3 ) * ( 3 * 3 )
のようになる
コレを避けるためにseqを使えばよいとあったのですが試しに
import Debug.Trace
square x = x * x
const3 = trace "*" 3
main = do
print
$ square $ square $ square $ square $ square
$ square $ square $ square $ square $ square
$ square $ square $ square $ square $ square
$ const3
みたいなプログラムで試してみました
もし説明通りならconst3が2^15回呼ばれて*がいっぱい出てきそうですが、やってみると*は一個しか出てきません
コレは何故ですか?
ちなみにghcです
ghcがconst3の結果を自分で勝手に“メモ化”してよきにはからってくれているんでしょうか?
49: デフォルトの名無しさん [] 2022/01/16(日) 14:36:08.72 ID:f2QwXzzi(2/4) AAS
>>48
仕様なんですか?
Language Reportかなんかに書いてありますか?
50: デフォルトの名無しさん [] 2022/01/16(日) 14:39:15.35 ID:f2QwXzzi(3/4) AAS
何かの文章は "ウォークスルー Haskell" というやつでした
http://walk.northcol.org/haskell/eval-strategies/
3 ではなく 1 + 2 でやってました
52: デフォルトの名無しさん [] 2022/01/16(日) 18:54:16.95 ID:f2QwXzzi(4/4) AAS
>>51
square x = x * x
を
square x = seq x $ x * x
にして明治的に“xを評価してからx*xを計算せよ”に変えるともちろん*ひとつです
それは納得いきます
ウォークスルーHaskellにもそうなると書いてあるしHaskell Language Report 2010にもseqで正格評価になると書いてあります
なのでコレは納得いくんですがseqなしの場合の動作が文書と異なるように見えます
もちろん参照透過性があるので一度計算した結果をメモ化して再利用しても同じ答えにならないといけないので答え自体は同じになるわけですけど
コレはたまたまGHCの開発者が優秀でHaskellの標準動作としては保証されない事までやってくれてるだけなのか、標準動作としてメモ化しないといけないことになってるのかどっちだろうと
今のところ今自分が勉強してるプログラムにはseq入れて明治的に正格評価してもらってるんですけど標準でメモ化してくれるなら消せるしスッキリするし、あるいは明示しないと他の処理系だとしてくれないなら残しとかないといけないし
上下前次1-新書関写板覧索設栞歴
スレ情報 赤レス抽出 画像レス抽出 歴の未読スレ AAサムネイル
ぬこの手 ぬこTOP 0.027s