[過去ログ]
関数型プログラミング言語Haskell Part33 (1002レス)
関数型プログラミング言語Haskell Part33 http://mevius.5ch.net/test/read.cgi/tech/1581326256/
上
下
前次
1-
新
通常表示
512バイト分割
レス栞
抽出解除
レス栞
このスレッドは過去ログ倉庫に格納されています。
次スレ検索
歴削→次スレ
栞削→次スレ
過去ログメニュー
リロード規制
です。10分ほどで解除するので、
他のブラウザ
へ避難してください。
703: デフォルトの名無しさん [sage] 2021/02/04(木) 22:24:53.84 ID:w5MK0dgi >>702 ありがとうございます 参考にさせていただきます そうですね もう一つ可読性が欲しい感じがします 元々の問題意識としては私は可読性の高いコードが要求されることが多いのです 例えばFibonacci数列であれば f n = ( f $ n -1 ) + ( f $ n - 2 ) に可読性においてまさるものはないのですが、もちろんこれでは遅くて使い物になりません なので実用性も多少はなりとも求めるならある程度は可読性を犠牲にせざるを得ないのですが、どういう方法がいいのだろうというのがテーマなのです でたまたまFibonacciの場合に f = 0 : 1 : ( zipWith ( + ) f $ tail f ) というのを見つけてコレ中々いいなと、dpで計算してるのに“メモ”をするための不要な手続きを書く必要がなく、Haskellの“call by need”の機能をうまく利用してdp計算させてるところにちょっと唸ったもので でどれくらいコレでいけるのかなと二重数列をやってみたらうまくいかなくて、どうしたもんかなと まぁコレはしょうがないのかもしれませんけど http://mevius.5ch.net/test/read.cgi/tech/1581326256/703
704: デフォルトの名無しさん [sage] 2021/02/05(金) 00:47:44.85 ID:hZ1aOePg >>703 方向性違うかなと思いつつ書いたんですがやっぱり違いましたね。失礼しました。 今更どうでもいいですがちょっと間違えたので訂正だけさせてください。 comb7_1 = (repeat 1 :) $ (map (scanl (+) 1 . tail) $ comb7_1) http://mevius.5ch.net/test/read.cgi/tech/1581326256/704
707: デフォルトの名無しさん [sage] 2021/02/05(金) 19:44:21.42 ID:DBOaHn9B >>703 その遅くて使い物にならない計算を、 可読性をあまり犠牲にしないで爆速にする方法に、 メモ化(memoization)というテクニックがあります。 (その代わり、当然メモリを使います) メモ化関数 memoize が用意されていれば、 n 番目のフィボナッチ数を求める関数 fib は 次のように書けます。 -- メモ化 fib :: Int -> Integer fib = fix (memoize . fib') -- フィボナッチ計算の本体 fib' :: (Int -> Integer) -> Int -> Integer fib' f 0 = 0 fib' f 1 = 1 fib' f n = f (n-1) + f (n-2) メモ化関数を提供するパッケージは色々あります。 また、メモ化の仕組みの基礎や本質を学びたいのなら、 次のごく短いブログ記事がおすすめです。 https://kseo.github.io/posts/2017-01-14-memoization-in-hasekll.html この記事の最後の fibMemo 関数について、 適当な小さな値に適用させたものを 自分でノートに展開してみるといいです。 http://mevius.5ch.net/test/read.cgi/tech/1581326256/707
709: デフォルトの名無しさん [sage] 2021/02/06(土) 09:10:00.64 ID:8eeMDweD >>707 解説ありがとうございます やはりメモ化するしかないんだと思います 問題はそれがプログラマが明示的に自分でやらないといけないのか、コンパイラが自分でやってくれるのかの差なんだと思います Haskellは純粋なcall by nameではなく、call by needのシステムの中にメモ化を備えていてプログラマがメモ化するように書いてなくても勝手にメモ化できるものをメモ化してくれるのがすごいとこだと思うんですけど、例えば>>703の2番目の例で最初見た時「なんでこの定義式でメモ化が効くんだ?」とさっぱりわからなかったのが、実はHaskellのcall by needのシステムをうまく利用してるらしいとわかったのが最初なんです で二重の漸化式だとうまくいかないなと もちろん二重の全炊きでも上手くsuffixの取り方を変えたりすると同様の方法でメモ化できるんですけど、それでは結局「Haskellの機能を利用して明示的にメモ化を指定することなく高速化した」事にはなりません まぁコレはしょうがないんでしょうね どんな計算も常にメモ化して常に同じ評価式を2度扱う事を防いでたらそんなの逆に使い物になりませんからね http://mevius.5ch.net/test/read.cgi/tech/1581326256/709
712: デフォルトの名無しさん [sage] 2021/02/06(土) 21:12:54.72 ID:HlAr7yEc >>709 今回の話の本質ではないので、へーそうなんだ、 程度に聞いてくれればいいのですが、 >>703 の2番目の例とは、 f = 0 : 1 : zipWith (+) f (tail f) のことでしょうか。 もしそうなら、これはメモ化ではないですよ。 (このテクニックをなんと呼ぶのかは知りませんが) メモ化というのは簡単にいえば、 関数の同じ引数に対する2度目(以降)の適用に備えて、 その引数に対する1度目の関数の値をその引数とペアにして どこかにメモしておくことです。 ポイントは、2度目以降に備えることではなく、 引数と関数値のペアをメモしておくことです。 それを踏まえて、>>703 の2番目の例において、 では何が関数で、引数と関数値のペアはどこにメモされているか、 考えてみてください。 ただ、言葉の意味は時代と共に変化していくものなので、 今はこれも広義にメモ化と言うことになっているのでしたら、すいません。 私の方が勉強不足です。 http://mevius.5ch.net/test/read.cgi/tech/1581326256/712
メモ帳
(0/65535文字)
上
下
前次
1-
新
書
関
写
板
覧
索
設
栞
歴
スレ情報
赤レス抽出
画像レス抽出
歴の未読スレ
AAサムネイル
Google検索
Wikipedia
ぬこの手
ぬこTOP
0.037s