[表示 : 全て 最新50 1-99 101- 201- 301- 401- 501- 601- 701- 801- 901- 1001- 2ch.scのread.cgiへ]
Update time : 07/21 14:46 / Filesize : 290 KB / Number-of Response : 1014
[このスレッドの書き込みを削除する]
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧] [類似スレッド一覧]


↑キャッシュ検索、類似スレ動作を修正しました、ご迷惑をお掛けしました

関数型プログラミング言語Haskell Part30



1 名前:デフォルトの名無しさん mailto:sage [2017/01/15(日) 23:43:54.28 ID:Vh4eztBk.net]
関数型プログラミング言語 Haskell について語るスレです。

haskell.org (公式サイト)
www.haskell.org/

前スレ
関数型プログラミング言語Haskell Part28
echo.2ch.net/test/read.cgi/tech/1428597032/

792 名前:デフォルトの名無しさん mailto:sage [2017/08/05(土) 04:37:17.71 ID:2UARNcsu.net]
>>782
メモ化は空間計算量と引き換えに高速化する話だからむしろ逆のような
フィボナッチで言うならInteger 3個分のメモリがあればn番目が計算できるでしょって話だから
タプリングの方が解決策としては近いと思う

結局リストで定義しちゃうと(そして評価しちゃうと)
そのイミュータブル性のために各要素はまた参照されるかもしれないから
GHCは捨てられないんだと思ってる

793 名前:デフォルトの名無しさん mailto:sage [2017/08/05(土) 05:35:09.29 ID:pRMdXxul.net]
/usr/bin/time -f "sec: %e\tmem: %M"

n=13

>>775の sec: 0.36 mem: 89032
https://paiza.io/projects/EvT2VA9nWlsu95GfM7llhA

>>776の replicateM は sec: 0.38 mem: 89016 と確かにメモリそう変わらない
https://paiza.io/projects/-jBpd8K5u3IcfeqromaImg

>>777の変な奴は sec: 0.86 mem: 3856 と確かにメモリ少ないけど時間かかりすぎ
https://paiza.io/projects/k_jsvUVfq54JyTaA691CaQ

>>782の iterate は sec: 0.36 mem: 77668 と少しメモリ小さい
https://paiza.io/projects/rb9bWzNuI410te_SxtMqMw

794 名前:デフォルトの名無しさん mailto:sage [2017/08/05(土) 11:12:37.24 ID:xs6w3tHN.net]
iterateは良いよね
iterateはメモリを無限に使うとか予想したやつを退場させてから冷静な議論ができる

795 名前:デフォルトの名無しさん mailto:sage [2017/08/05(土) 11:39:14.63 ID:ZbIs+TkB.net]
好戦的

796 名前:デフォルトの名無しさん mailto:sage [2017/08/05(土) 13:37:30.60 ID:xs6w3tHN.net]
人間を退場させそうな勢いのAIに同じことが言えるのかね
好戦的AIの開発を禁止できるのか

797 名前:デフォルトの名無しさん mailto:sage [2017/08/05(土) 20:09:57.57 ID:O1n7JOVS.net]
Windowsでjupyterできませんか?

798 名前:デフォルトの名無しさん mailto:sage [2017/08/06(日) 00:35:09.20 ID:Q0UOjaQj.net]
>>785
haskell初心者の私が頑張ってみました

sec: 0.18 mem: 4024
https://paiza.io/projects/WzVPNUUH0xYOfCR99rLSVw

799 名前:デフォルトの名無しさん mailto:sage [2017/08/06(日) 14:15:08.49 ID:PBiILbDw.net]
私 (>>775) のや replicateM を使う方法は仮想的なツリーを深さ優先でたどります。
なので列挙したい型や、リストの要素数の影響をもろに受けるのですね。
(リストの要素ではなく、それを計算するためのサンクが大きい?)

一方で >>777 は10進数の値を一つずつn桁のk進数に変換しており、
また >>790 はn桁のk進数の値を0から順に1ずつ足しています (>>776 の後半のアイデア)。
共に理論上は1要素分のメモリしか必要ない方法なので、かなり省メモリなんですね。

理屈が分かってスッキリ

800 名前:オました。
みなさん、ありがとうございました。
[]
[ここ壊れてます]



801 名前:デフォルトの名無しさん mailto:sage [2017/08/07(月) 02:20:55.75 ID:LndoSP5N.net]
未評価のサンクじゃなくて最終的にn-1以下の評価済み結果を全て保持することになるからメモリを食うのでは?

802 名前:デフォルトの名無しさん mailto:sage [2017/08/07(月) 09:52:01.96 ID:/JDQv1Xc.net]
自由な長さのビットは標準ライブラリに無いのですか?

803 名前:デフォルトの名無しさん mailto:sage [2017/08/07(月) 11:32:36.95 ID:EbDwvOe5.net]
>>792
全てとは何個ですか
有限個なら定量的に書いてください
無限なら書かなくていいです

804 名前:デフォルトの名無しさん mailto:sage [2017/08/07(月) 20:00:07.36 ID:Nk2fFjGd.net]
>>789
dockerでihaskellだったら使ってる

805 名前:デフォルトの名無しさん mailto:sage [2017/08/07(月) 21:16:35.72 ID:AGrOxn5I.net]
>>792
そうでしょうか?

私の方法 (>>775) で data T = A|B|C の時に print $ enumerate 3 としてみると
[[A,A,A], [A,A,B], [A,A,C], [A,B,A], [A,B,B], ...] の順で評価されます。

外側リストの第1要素 [A,A,A] を評価し終えて次に第2要素 [A,A,B] を評価しようとする時、
[A,A,A] の第3要素の A はもう要らないので捨てて構わないはずです。
[A,A,B] の評価にまだ必要なのは第1要素と第2要素それぞれの A のみのはず。
さらに [B,A,A] まで評価が進めば、[A,A,A] から [A,C,C] まで評価した分はもう必要ありません。

そう考えると、enumerate n に常に必要なのは理論的には T 型の値 n 個分のみ。
評価済みの値の保持に必要なメモリ量は >>777>>790 の方法と同じです。

なので、評価済み結果の保持によってメモリが大きく消費されるのであれば、
>>777>>790 でも同様に大きなメモリを消費しているはずだと私は思うのですが、
どうでしょうか?

806 名前:デフォルトの名無しさん mailto:sage [2017/08/07(月) 21:17:23.45 ID:AGrOxn5I.net]
>>792
私が原因はサンクにあるのではと思ったのは次のことからです。

私の方法 (>>775) で enumerate 3 :: [[T]] の第1要素を評価しようとする時、
まず concatMap の引数である [minBound .. maxBound] の第1要素だけが評価され、
残りは未評価のまま残ります (正確には enumFromTo の結果の弱頭部正規化ですね)。
次に map (x:) enumerate (n-1) があるので enumerate 2 の第1要素を評価する必要があります。
enumerate 2 でも同様のことが起こります。
これ、全部評価されつくされるまで、深さ分だけずっと残りますよね。

enumerate 自身が深さ方向にたどるごとに毎回呼ばれ、評価し切る前にまた呼ばれるので、
未評価で残るのは [minBound .. maxBound] の部分だけではないと思います。

このようなことが積み重なって、大量のメモリ消費に繋がっていると私は考えました。
リストを消費して何かを計算する関数に使うリストそのものを再帰的に作ると、
たぶん似たような事(無駄なメモリ消費)が起こるのではないかと思います。

807 名前:デフォルトの名無しさん mailto:sage [2017/08/08(火) 00:32:40.42 ID:ix2x2634.net]
sumじゃなくlenghtで計算すると>>790のでもメモリ使うんだね

>>775のsec: 0.19 mem: 89068
https://paiza.io/projects/CqJoDIkGAnH7qGSCKEAiyQ

>>790のsec: 0.09 mem: 49084
https://paiza.io/projects/L4gRQ7RM5z3XFGf_Wu1YvQ

808 名前:デフォルトの名無しさん mailto:sage [2017/08/08(火) 03:20:35.89 ID:fUnlTWTU.net]
副作用の無い関数は同じ引数で毎回同じ戻り値になることが保証されてます

n=2のとき
enumerate 2 = concatMap (\x -> map (x:) (enumerate 1)) [A,B,C]
となります
[A,A]..[A,C]まで評価が終わったとき enumerate 1 = [[A],[B],[C]] が評価済みとなり再利用が可能となり
enumerate 2 = [A,A] : [A,B] : [A,C] : concatMap (\x -> map (x:) [[A],[B],[C]]) [B,C]
となり n-1 すなわち n=1 のときの結果が保持されることが分かります

同様にn=3のとき同じことが生じ
enumerate 3 = [A,A,A] : ... : [A,C,C] : concatMap (\x -> map (x:) [[A,A], ... ,[C,C]]) [B,C]
のようになり n-1 すなわち n=2 のときの結果が保持されることが分かります

また n=3 のとき n=1 の結果の [[A],[B],[C]] の各要素は n=2 の結果から参照されてます
すなわちGC可能な対象は 中身の[A] [B] [C]ではなく[,,,]の外側の部分だけです
(もちろんまだ enumerate 1 をどこか呼び出される可能性があるならGCはされませんが…)

ここまで言えば>>792の意味がわかりますね?

はい

809 名前:デフォルトの名無しさん mailto:sage [2017/08/08(火) 03:28:04.28 ID:fUnlTWTU.net]
なおサンクを気にされてたようですが
サンクを気おつけるべきは>>790のようなコードだと私は考えますが
lastを取れば分かります
https://paiza.io/projects/lmYXW-sssdTlAIGrju4u9g

810 名前:デフォルトの名無しさん mailto:sage [2017/08/08(火) 03:45:42.60 ID:aoRcppZr.net]
>>796
>外側リストの第1要素 [A,A,A] を評価し終えて次に第2要素 [A,A,B] を評価しようとする時、
>[A,A,A] の第3要素の A はもう要らない

後ろ二つ [A,A]は、[A,A,A],[B,A,A],[C,A,A]で共有されるから
そこで捨てるわけにはいかないんじゃないかな



811 名前:デフォルトの名無しさん mailto:sage [2017/08/08(火) 04:31:27.11 ID:shTh0A51.net]
詳しい情報サンクス

812 名前:デフォルトの名無しさん mailto:sage [2017/08/08(火) 21:31:40.60 ID:OEct+pCd.net]
>>799
すいません、まだ良く理解できていません。
2点確認させてください。


まず、1行目でおっしゃっているのは参照透過性のことですよね。


次に、3行目以降でおっしゃっていることですが、それは本当ですか?
それだと勝手にメモ化が行われているように私には見えるのですが。

例えば f x = x*2 という関数が定義されているとします。
その時に、別の関数 g の定義の中で、

let a = f 1; b = f 1 in ...

とやっても、1度目の g の呼び出しで 1*2 の計算結果は再利用されませんよね。
a の束縛時と b の束縛時で、計 2 回同じ計算がされると思います。

1度目の g の呼び出しで a や b が 2 と評価された後、再び g が呼ばれた時は、
a や b はもう関数 f ではなく値 2 を指していますから、
これを以て「保存される」「再利用される」と言うのは理解できます。

以上のことから、enumerate 1 = [[A], [B], [C]] のリストも、
このままでは再利用されないと思うのですが。
再利用するには、計算結果を変数に束縛する必要がありませんか。


変なことを言っていたらすいません。

813 名前:デフォルトの名無しさん mailto:sage [2017/08/08(火) 21:58:17.33 ID:aoRcppZr.net]
>>803
>再利用するには、計算結果を変数に束縛する必要がありませんか。

mapの引数として束縛されるんじゃないの? >>775

814 名前:デフォルトの名無しさん mailto:sage [2017/08/08(火) 22:23:03.19 ID:OEct+pCd.net]
>>804
仮引数が束縛しているのはそのスコープ内だけだと思っていましたが、
違うのでしょうか。

let a = map id (enumerate 1); b = map id (enumerate 1)

これは2度同じ計算 (enumerate 1 の評価) がされませんか?

815 名前:デフォルトの名無しさん mailto:sage [2017/08/08(火) 22:33:15.60 ID:aoRcppZr.net]
実際に起こっているのはこういうことなんだろうな

let a = map id (enumerate 1); b = a; c=a

816 名前:デフォルトの名無しさん [2017/08/09(水) 00:17:08.56 ID:VTzajaTq.net]
>>799-800
嘘乙

817 名前:デフォルトの名無しさん [2017/08/09(水) 02:22:31.31 ID:mQsXelmt.net]
Glasgow Haskell Compiler上の遅延オブジェクト再利用手法の設計と実装
https://www.jstage.jst.go.jp/article/jssst/32/1/32_1_253/_pdf

818 名前:デフォルトの名無しさん mailto:sage [2017/08/09(水) 05:51:36.85 ID:L1lV7cdZ.net]
・愚直にパラメーターマシマシの関数
・そのごちゃごちゃしたパラメーターをデータ構造にまとめてコードの視認性と一目理解可能性を向上したコード

後者が前者より2倍近く時間かかって悲しい
データ構造の更新に思いの外時間がかかってるのだろうか

データ構造の一部だけ更新って、変える部分だけ新しく作って、後のパラメーターは元のデータのそれへポインタコピーするだけだと思うんですけど
それでもオーバーヘッド嵩むもんなんすかね


ごちゃごちゃ版の、一つパラメーター更新して再帰で関数呼び出すだけなのと、
データ構造にまとめた版の(データ構造の)一つパラメーター更新して再帰で関数呼び出すのとは
何が処理の手間的に違うんですかね


いいからパラメーター全部そのまま関数に並べ立てた方が速いんだよって言われてるようで悲しい

性能を犠牲にせずにメンテ力アップしたい

819 名前:デフォルトの名無しさん mailto:sage [2017/08/09(水) 05:57:53.35 ID:L1lV7cdZ.net]
多くの場合を受け取って、後でcaseなどで引数の場合分けをするより
トップレベルで最初に引数のパターンマッチで場合分けしてから始める書き方の方が速いんですかね

後者はなんか何度も関数名書かなきゃいけなくて汚い感じするんですが。同じlet式もボイラープレートのようにまた書かなきゃならないし

でも後者の方が高速動作する(経験則)みたいで悔しい

820 名前:デフォルトの名無しさん mailto:sage [2017/08/09(水) 07:31:58.59 ID:azQJOuJj.net]
vectorパッケージ使ってて、ベンチマークとるとVector.Fusion.UtilとVector.Fusion.Stream.Monadicにリソースが割かれてるんだけど、
stream fusionてコンパイル時に効いてて、ランタイム時には出てこないと思ってたのだが、違うんかね?



821 名前:デフォルトの名無しさん [2017/08/10(木) 00:20:12.66 ID:joXozDrb.net]
本物のプログラマはHaskellを使う - 第31回
itpro.nikkeibp.co.jp/article/COLUMN/20090512/329783/
> これは,GHCの最適化機能の一つである「共通部分式の削除(CSE:Common Subexpression Elimination)」によって,共通する式「unsafeVal 10」がメモ化されたためです。これにより「unsafeVal 10」は1回しか評価・実行されなくなってしまいます。

822 名前:デフォルトの名無しさん [2017/08/10(木) 00:21:53.72 ID:joXozDrb.net]
> Haskellには第8回で説明した「メモ化」という機能があるため,同じ式が複数回,評価・実行されることはありません。

823 名前:デフォルトの名無しさん mailto:sage [2017/08/10(木) 01:41:50.38 ID:wtM226NM.net]
>>809
パラメータごちゃごちゃってのが多引数関数なら、Haskellの関数はカリー化されてるので
変更するパラメータの箇所によっては関数定義が使いまわせて効率がよくなってる、かも

末尾再帰化で局所関数作ってやるみたいに、
外からは定義したデータ構造で受け取って、
関数内で再帰回すときはばらした局所関数を使うとかはどうか

824 名前:デフォルトの名無しさん mailto:sage [2017/08/10(木) 06:48:00.63 ID:Gy6ZNt2K.net]
メモ化じゃなくてグラフ簡約では?

825 名前:デフォルトの名無しさん mailto:sage [2017/08/10(木) 07:14:52.40 ID:7mVrofJh.net]
itpro.nikkeibp.co.jp/article/COLUMN/20070305/263828/
>本物のプログラマはHaskellを使う
>第8回 遅延評価の仕組み
>この問題を解決するのが必要呼び出しです。必要呼び出しでは,
>同じ変数から束縛された項はポインタによって共有され,
>一度簡約された項をもう一度使用する場合には最初の計算によってキャッシュされた解を利用します。
>項を共有することにより,構文はもはや通常の木構造ではなくグラフ(graph)構造を取ることになります。
>そのため,このような簡約方法を「グラフ簡約(あるいはグラフ簡約法,graph reduction)」と呼びます。
>また,同じ式の評価のために,キャッシュされた解を使う手法のことを「メモ化(memoization)」といいます。

826 名前:デフォルトの名無しさん mailto:sage [2017/08/10(木) 11:53:35.98 ID:Mbfm9qrf.net]
共通部分式削除か
もしバグの原因が最適化だったら簡単だな
最適化を無効にするだけでわかる

827 名前:デフォルトの名無しさん mailto:sage [2017/08/10(木) 15:16:55.85 ID:7Zrve9l8.net]
共通部分式削除ではないしバグでもない

828 名前:デフォルトの名無しさん mailto:sage [2017/08/10(木) 16:49:36.71 ID:R2w5AQk8.net]
ぼく、グラフ簡約がいつされていつされないのかよく解ってない(`・ェ・´)

829 名前:デフォルトの名無しさん [2017/08/10(木) 22:16:48.24 ID:fh9/jf6h.net]
基本的なこと
www.kotha.net/hperf/basics.html
> 関数の自動メモ化はない
> Haskellの関数は同じ引数で呼ぶと同じ結果を返すので透過的にメモ化が可能だが、GHCはそれを行わない。
> 局所的な最適化によってメモ化と同じ結果になることはあるが、一般には期待できない。
> メモ化が必要なら「引数->結果」の対応を保存するデータ構造(Map、Arrayなど)を明示的に用意する必要がある。

830 名前:デフォルトの名無しさん [2017/08/10(木) 22:27:51.24 ID:fh9/jf6h.net]
GHCのこと
www.kotha.net/hperf/ghc.html
> プログラムの低水準の振る舞い(たとえば、「このループでメモリ確保は発生する?」「この式はどのタイミングで評価される?」)を理解したり、GHCの最適化の結果を見たりするのには、Core言語形式の中間出力を読むと良い。
> 特に、小さいループを可能な限り高速化したい場合など、最適化後のCore出力を比較しながらコードをいじるのが有効なことがある。
> Core形式の最終形(最適化された後、STG言語に変換される直前)は-ddump-prepで読める。



831 名前:デフォルトの名無しさん mailto:sage [2017/08/10(木) 23:42:17.05 ID:7Zrve9l8.net]
>>820
www.kotha.net/hperf/basics.html
Haskellの言語仕様(ja)は式の評価順序を定めていないが、
GHCを始めとする有名な処理系は全て「必要呼び(call by need)」という評価戦略を基本にしている。

必要呼び戦略のもう一つの特徴は引数の自動メモ化である。
ある関数の仮引数が、その関数の本体に複数回出現したとしても、対応する実引数の評価は高々一回しか発生しない。

832 名前:デフォルトの名無しさん mailto:sage [2017/08/11(金) 00:45:37.86 ID:Ze2QVHug.net]
困ったときはhaskell-masterことtanakhに助けを求める

833 名前:デフォルトの名無しさん mailto:sage [2017/08/11(金) 03:54:12.02 ID:7orZPIZ6.net]
フィボナッチ数を漸化式で単に実装したとき、そのままだと深い部分で同じ引数による呼び出しが無数に発生してると思うんですが
自動メモ化してくれないんすね

834 名前:デフォルトの名無しさん mailto:sage [2017/08/11(金) 04:15:27.98 ID:L7AEIGon.net]
>>824
それは>>820のほうで >>775で起こる「メモ化」は>>816だろ

835 名前:デフォルトの名無しさん mailto:sage [2017/08/11(金) 05:49:13.91 ID:ZqUin61F.net]
言語別平均年収ランキング

1位Scala 626万円
2位Python 601万円
3位Kotlin 577万円
4位Swift, Ruby 562万円
6位Java 552万円
7位Perl 551万円
8位 C言語 538万円
9位JavaScript 536万円
10位PHP 522万円
11位COBOL 509万円

以下は求人が少ないためランキングから除外
Groovy 680万円
Haskell 670万円
Erlang 604万円
LISP 581万円

尚、C++, C#は調査対象外とする

836 名前:デフォルトの名無しさん mailto:sage [2017/08/11(金) 10:48:20.88 ID:Ca8C76qb.net]
>>826
>尚、C++, C#は調査対象外とする
なぜなんだ?それこそ興味深いんだが?

837 名前:デフォルトの名無しさん mailto:sage [2017/08/11(金) 10:55:08.08 ID:mLIKyCPo.net]
難しすぎて習得者が少なすぎて調査不能なんだろう

838 名前:デフォルトの名無しさん [2017/08/11(金) 11:06:36.65 ID:QQDjRimB.net]
求人数が少ないから除外?
どうしてもその言語じゃなきゃだけど、その言語使える人が少ないって方が給料良いんだが。
(あと金出す側の資金力にもよる)

Fortranとか意外と良いぞ。
金融系なら関数型言語。

839 名前:デフォルトの名無しさん [2017/08/11(金) 11:07:39.31 ID:QQDjRimB.net]
あ、Fortranは大学がスパコンで使うとかの場合ね。

840 名前:デフォルトの名無しさん mailto:sage [2017/08/11(金) 11:15:12.10 ID:07jWFZnC.net]
いやC++C#は



841 名前:スいだろうよ []
[ここ壊れてます]

842 名前:デフォルトの名無しさん mailto:sage [2017/08/11(金) 11:32:50.22 ID:eQbA+Atw.net]
なぜ 828 がジョークだと分からないんだw

831 も 829 にマジレスするなら、828 がジョークだと教えないと
(まさか 831 は 828 に対してのレスってことはないよね?)

843 名前:デフォルトの名無しさん mailto:sage [2017/08/11(金) 14:56:02.48 ID:0Mux6fCC.net]
>>826の元記事はこれ
プログラミング言語別の平均年収ランキング、1位は「Scala」 - ITmedia NEWS
www.itmedia.co.jp/news/articles/1708/10/news073.html

844 名前:デフォルトの名無しさん mailto:sage [2017/08/11(金) 20:01:49.81 ID:rgIYrPBr.net]
グラフ簡約で物理同値が保証されてることを「メモ化」とはいわなくない?

845 名前:デフォルトの名無しさん mailto:sage [2017/08/11(金) 20:33:13.01 ID:o2mcpSct.net]
>>834

>>816
>そのため,このような簡約方法を「グラフ簡約(あるいはグラフ簡約法,graph reduction)」と呼びます。
>また,同じ式の評価のために,キャッシュされた解を使う手法のことを「メモ化(memoization)」といいます。

846 名前:デフォルトの名無しさん mailto:sage [2017/08/11(金) 21:13:47.87 ID:eQbA+Atw.net]
メモ化って memorization の訳だと思ってたが、 memoization という造語(1968年初出)の訳だったのか

んで、メモ化は簡約結果が同値であることを利用して、
計算結果を使いまわす研究での用語だったみたいね

ttps://ja.wikipedia.org/wiki/メモ化

847 名前:デフォルトの名無しさん [2017/08/12(土) 00:24:09.94 ID:yWjB6ujN.net]
Haskell でのデバッグ - あどけない話
d.hatena.ne.jp/kazu-yamamoto/20120606/1338957783

848 名前:デフォルトの名無しさん [2017/08/12(土) 19:28:27.04 ID:G1Oa8HnK.net]
i.imgur.com/Aso3WgV.png

メモ化ってどうやるの?

849 名前:デフォルトの名無しさん mailto:sage [2017/08/12(土) 21:06:06.85 ID:vdGf/ex1.net]
参照透明性を利用する
一度評価したらもう動かないのだという性質を利用するのだ
コンテナと組み合わせてほら!

850 名前:デフォルトの名無しさん mailto:sage [2017/08/12(土) 22:47:13.92 ID:zuB4Y/rr.net]
>>838
trace関数のソースにこう書かれてた

The 'trace' function should /only/ be used for debugging, or for monitoring
execution. The function is not referentially transparent: its type indicates
that it is a pure function but it has the side effect of outputting the
trace message.

他の関数と同様に考えるわけにはいかないようだ



851 名前:デフォルトの名無しさん mailto:sage [2017/08/13(日) 00:48:15.11 ID:SYaWjJhn.net]
Python, Kotlin, underscore.js にも、memoize がある

ナップサック問題で、使う

852 名前:デフォルトの名無しさん [2017/08/13(日) 01:44:46.49 ID:Pg7jRQiA.net]
Let vs. Where - HaskellWiki
https://wiki.haskell.org/Let_vs._Where#Lambda_Lifting

これってwhereは引数に変換されるってこと?(英語うまく訳せなくて分からない)

853 名前:デフォルトの名無しさん mailto:sage [2017/08/13(日) 06:26:42.63 ID:BxbLY5/X.net]
競技プログラミングではデフォルトライブラリしか使えないので
高度なアルゴリズムは自分で勉強して実装しておいたものをコピペするしかないのだ

854 名前:デフォルトの名無しさん [2017/08/13(日) 10:34:38.57 ID:fRo9GRp1.net]
モナドってなんなの?

855 名前:デフォルトの名無しさん mailto:sage [2017/08/13(日) 12:11:08.44 ID:ndxDWak1.net]
文脈

856 名前:デフォルトの名無しさん mailto:sage [2017/08/13(日) 13:12:26.05 ID:mWeUlEpW.net]
山本タソは「裏面配線」って言ってたかな

857 名前:デフォルトの名無しさん [2017/08/13(日) 17:47:54.48 ID:fRo9GRp1.net]
関数プログラミングって文字列型って上手くあつかえるの?
オブジェクト指向の最大の欠点って「文字列を上手く扱えない」ところに
あると思うんだよね。

858 名前:デフォルトの名無しさん [2017/08/13(日) 17:51:31.77 ID:fRo9GRp1.net]
>>846
何か「表面」があっての裏面配線なんだろ?
ではその表面って何?

859 名前:デフォルトの名無しさん mailto:sage [2017/08/13(日) 19:22:11.54 ID:zbgzOget.net]
>>842
違うよ。

ある関数の定義に使う補助的な関数の定義は、独立してトップレベルに置く事もできるし、
let や where を使って関数定義の中に置く事もできるよ、って言ってる。

関数内部で定義されていた関数を外に出して独立させることを lambda lifting と言って、
逆に外にあった関数を別の関数の内部で定義することを lambda dropping と言うんだ。

Haskell を使うだけならこんな理解で十分なんだけど、
もともとは関数型言語の処理系の研究で出てきた用語なんで、
その辺りまで深く学びたいのなら、やつぱり英語を読めないと難しいかも。


ちなみに、そのリンク先の [3 Lambda Lifting] と比べれば、
その直後の [4 Problems with where] の方が衝撃的な内容だね。
Haskell を実用的に使っている人にとってはこっちの方が大事な内容だよ。

860 名前:デフォルトの名無しさん mailto:sage [2017/08/13(日) 20:15:07.01 ID:DrQ+cSjE.net]
Haskellという土台の上に、オレオレ言語を構築する。それがモナドだ

Haskell上で動作する『ぼくのかんがえたさいきょうのげんご』

DSLプラットフォーム



861 名前:デフォルトの名無しさん mailto:sage [2017/08/13(日) 20:19:51.10 ID:qvBBF+tW.net]
>>849
衝撃だけど実際どれくらいパフォーマンス上のインパクトがあるの?

862 名前:デフォルトの名無しさん mailto:sage [2017/08/13(日) 21:59:10.19 ID:zbgzOget.net]
>>851
試せばすぐに分かるが、あのフィボナッチ数のサンプルでは全く大した事なかったりする。
確かに後者の方が遅い代わりにメモリ効率いいけど、ほとんど差が出ない事に驚くほどだよ。

差がはっきり出る例を作る方が難しいと思う。


衝撃なのはパフォーマンスの差じゃなくて、単に引数を省略しただけで
コンパイルの結果に差が出ることがある、という事実。

GHCにはこういうことがあると、頭の片隅にでも入れておいた方がいいね。
他にも「単に***を変えただけで何で意図したように動かないの?」
ってなるようなコンパイラの仕様があるだろうから、
それに出くわした時に、もしかしてと気づければ無駄に悩む時間が省ける。

863 名前:デフォルトの名無しさん mailto:sage [2017/08/13(日) 22:05:27.98 ID:IBmKuvX6.net]
STモナドとSTArrayの理解を深めるのに向いてる書籍やサイトなどがあれば英語でもいいので教えていただきたいです
競技プログラミングで少し行き詰まってて

864 名前:デフォルトの名無しさん mailto:sage [2017/08/13(日) 22:12:47.72 ID:qvBBF+tW.net]
>>852
なるほど
関数プログラミング入門か実践入門あたりの和書でもポイントフリーか否かで
動作が変わるという内容を見たことはある

865 名前:デフォルトの名無しさん mailto:sage [2017/08/13(日) 22:35:47.24 ID:3dVRXwBQ.net]
>>851
fib1 40は1秒かからなかったけど
fib2 40だと37秒かかった

fib1 = (map fib1' [0 ..] !!)
where
fib1' 0 = 0
fib1' 1 = 1
fib1' n = fib1 (n - 1) + fib1 (n - 2)

fib2 x = map fib2' [0 ..] !! x
where
fib2' 0 = 0
fib2' 1 = 1
fib2' n = fib2 (n - 1) + fib2 (n - 2)

866 名前:デフォルトの名無しさん mailto:sage [2017/08/13(日) 22:42:29.03 ID:3dVRXwBQ.net]
>>855
fib1 43は1秒かからなかったけど
fib2 43は2分40秒かかった

867 名前:デフォルトの名無しさん [2017/08/13(日) 22:56:30.39 ID:Pg7jRQiA.net]
>>849
教えてくれてありがとう

868 名前:デフォルトの名無しさん mailto:sage [2017/08/13(日) 23:03:01.35 ID:Kt+T0SXe.net]
毎回 let 束縛し直すから遅い、って凄えなこれ
手動 eta-reduction 必須、みたいなんか

869 名前:デフォルトの名無しさん mailto:sage [2017/08/13(日) 23:18:59.79 ID:AxVfgjdD.net]
>>855
fib3 40、fib4 40は fib2 40と同じくらい

fib3 =
let fib3' 0 = 0
fib3' 1 = 1
fib3' n = fib3 (n - 1) + fib3 (n - 2)
in (map fib3' [0 ..] !!)

fib4 x =
let fib4' 0 = 0
fib4' 1 = 1
fib4' n = fib4 (n - 1) + fib4 (n - 2)
in map fib4' [0 ..] !! x

870 名前:デフォルトの名無しさん mailto:sage [2017/08/13(日) 23:39:51.65 ID:DrQ+cSjE.net]
>>842
なにこれこわい



871 名前:デフォルトの名無しさん mailto:sage [2017/08/14(月) 00:09:46.90 ID:CgEdc2Wx.net]
>>855
最適化オプションを付けてコンパイルしてみ。
ほとんど差が無くなるから。

872 名前:デフォルトの名無しさん [2017/08/14(月) 00:40:48.93 ID:qlMtZwAF.net]
>>840
traceはメモ化には使えないってことですか

>>851-852
試してみた
使用メモリがだいぶ違う、低スペックPCなので20でも実行時間に差が出た
i.imgur.com/lJUUCAs.png
i.imgur.com/zXHSwNH.png

873 名前:デフォルトの名無しさん mailto:sage [2017/08/14(月) 01:18:11.31 ID:BK9BhUbr.net]
モナドを取り入れると明らかに型が違うのが分かる
Identityモナドでもいいんだが
問題なのは引数の省略ではなくコンストラクタの省略ではないか

fib1 = return (map fib [0 ..] !!)
fib2 x = return (map fib [0 ..] !! x)

874 名前:デフォルトの名無しさん mailto:sage [2017/08/14(月) 01:40:22.76 ID:tyQzDLaM.net]
呼び出し毎の関数束縛が遅いってことかね
値の束縛やトップレベルの関数呼び出しだとどの程度だろう

875 名前:デフォルトの名無しさん mailto:sage [2017/08/14(月) 03:27:39.46 ID:YjoaiCYq.net]
>>861
たしかに最適化で差異がなくなった


最適化なし -O0
fib1 (sec: 0.00 mem: 3456) https://paiza.io/projects/0LYONUr9fsU2GCX0AE8A_g
fib2 (sec: 0.87 mem: 4608) https://paiza.io/projects/iNAIEVZM5IY5uLxzJ_QJ7w


最適化あり -O1
fib1 (sec: 0.00 mem: 3280) https://paiza.io/projects/XCnm40B0C1HcbuAIBGyUFw
fib2 (sec: 0.00 mem: 3312) https://paiza.io/projects/Et1N4r-vdxXjrid_7hn6PA


計測手段 /usr/bin/time -f "sec: %e\tmem: %M"

876 名前:デフォルトの名無しさん mailto:sage [2017/08/14(月) 05:10:48.34 ID:8PjQyPOp.net]
最適化かくにん!

   よかった。

877 名前:デフォルトの名無しさん mailto:sage [2017/08/14(月) 12:00:31.24 ID:vFMuIdhl.net]
やはり、最適化かかってんのね。
安心したけど書いてるのがもう少し速くなるかなと思ってたので、残念なような、、

linuxでgtk2hsでつくってたのをwin10に移植しようとしたら、うまくいかなかった。
gtk2hsの公式も落ちてたし、HaskellのGUIは今は何が主流 or ポテンシャル高い、なんですかね?

878 名前:デフォルトの名無しさん [2017/08/14(月) 14:52:12.07 ID:yxoqAlkZ.net]
すまん、いろんなモナドをJavaとかPythonとかのコードで
表してくれ・・・
なんとなく言いたいことは分かったとしても、はっきりとモナドが
なんなのかが分からない。
クラスとは何が違うのか。

879 名前:デフォルトの名無しさん mailto:sage [2017/08/14(月) 15:06:44.92 ID:Au3l8RWH.net]
ひところ GUI の為の FRP に熱を上げていた連中は今、何に熱を上げてるの?

880 名前:デフォルトの名無しさん mailto:sage [2017/08/14(月) 17:17:03.93 ID:emaMcYYJ.net]
>>868
>すまん、いろんなモナドをJavaとかPythonとかのコードで
>表してくれ・・・

JavaかPythonのスレ逝くべきだと思うの

>なんとなく言いたいことは分かったとしても、はっきりとモナドが
>なんなのかが分からない。
>クラスとは何が違うのか。

「なんとなく」もわかってないと思うよ

あと「モナドは自己関手の圏におけるモノイド対象以上でも以下でもない」が本質的な回答



881 名前:デフォルトの名無しさん [2017/08/14(月) 17:29:31.74 ID:yxoqAlkZ.net]
>>870
お、イキリオタクか?
平たい言葉で説明できないやつは無能なんだよなぁ・・・
自分は頭いいとおもってる??かっこいいね??本質的な解答とかいっちゃってさ

882 名前:デフォルトの名無しさん mailto:sage [2017/08/14(月) 17:52:42.99 ID:emaMcYYJ.net]
CSにコンプレックスでもあんの?
テクニカルな概念をバカにわかるように説明しようとしてもムダってだけ

883 名前:デフォルトの名無しさん mailto:sage [2017/08/14(月) 18:03:28.37 ID:HwAT4qGf.net]
春先Haskell熱心にやってたが
いまはCとかアセンブラとかそんなんばっかw

884 名前:デフォルトの名無しさん mailto:sage [2017/08/14(月) 18:05:00.48 ID:HwAT4qGf.net]
圏論分からんのがここで
いくら吠えても無駄だとという…

885 名前:デフォルトの名無しさん mailto:sage [2017/08/14(月) 20:12:02.36 ID:IonSoW2j.net]
「左辺 <- 右辺」の右辺をモナドという
左辺と右辺が等しいとは言っていないので制約が少なくて便利

886 名前:デフォルトの名無しさん mailto:sage [2017/08/14(月) 20:17:22.67 ID:lpoYOEZY.net]
圏論を学ぶ為の知識がない

887 名前:デフォルトの名無しさん mailto:sage [2017/08/14(月) 20:37:31.10 ID:IonSoW2j.net]
letとwhereが炎上したのも
等しいと書いてあるのに時間とメモリの消費が違うのはおかしいって話だよな

888 名前:デフォルトの名無しさん mailto:sage [2017/08/14(月) 20:53:52.30 ID:FlMJ7oBL.net]
圏論もモノイドもわからなくてもHaskellでコード書くくらいは出来るけどな
もっと初学者への門戸を広げないと未来がない気がする

889 名前:デフォルトの名無しさん mailto:sage [2017/08/14(月) 22:55:23.88 ID:CgEdc2Wx.net]
>>867
最適化オプションで差がほぼ無くなるんだから、
俺は、どっちの書き方でも良い ==> 読みやすい方で書けばOK となって嬉しいけどな。

GUI ライブラリの主流は知らんけど、ポテンシャル高いのは Web アプリ系だと思ってる。
Webブラウザを GUI のキャンバスにするタイプのライブラリ。

基本的にはどのプラットフォームでも同じように動く。
既存の Web アプリ用テストフレームワークが使える。
この辺り、ライブラリ開発者にもアプリ開発者にも大きなメリットで、
要するに開発がしやすい。
これからどんどん進化していく可能性が高いんじゃないかな。

そんなライブラリはいくつかあるけど、俺は threepenny-gui がおすすめ。
ヘンに小難しい EDSL が無く、概念が素直でシンプルだからプログラムしやすいよ。
stackage にも入ってるから導入が楽だしね。

890 名前:デフォルトの名無しさん mailto:sage [2017/08/14(月) 23:10:56.01 ID:/MmIRMIQ.net]
>>879
情報ありがとう。
良い機会だしThree pennyやってみるよ。
上ででてるFRPとかいうのもやれそうで面白そうだし。



891 名前:デフォルトの名無しさん mailto:sage [2017/08/15(火) 02:45:23.70 ID:NWVlMToc.net]
>>842
2014年とかめっちゃ情報古いのでアテにならんだろ

Revision history of "Let vs. Where" - HaskellWiki
https://wiki.haskell.org/index.php?title=Let_vs._Where&action=history

892 名前:デフォルトの名無しさん mailto:sage [2017/08/15(火) 16:18:56.38 ID:5CT1InAk.net]
Chris Okasakiの純粋関数型データ構造
Haskellを志すキッズはマストバイだわ

まだ3章だけど、木の値の更新でどうやって効率良く(更新しない部分を)扱ってるのか解ったわ

根元から辿って、毎回関係ない方を共有してけば確かに辿るステップ分のコピーしか発生しないわけだわ
対数オーダーになるわけだわ
なるほどなるほど

SML記法で書いてあるけどHaskell式としてもすぐに頭に入るわ






[ 続きを読む ] / [ 携帯版 ]

前100 次100 最新50 [ このスレをブックマーク! 携帯に送る ] 2chのread.cgiへ
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧]( ´∀`)<290KB

read.cgi ver5.27 [feat.BBS2 +1.6] / e.0.2 (02/09/03) / eucaly.net products.
担当:undef