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

2025/01/10(金) 19:16:07.13ID:NIbIyPdh
一度死んだら復活は有り得んので注意な
2025/01/10(金) 19:39:05.74ID:N8eMPB8m
>>640-641
レスをありがとうございます

そうですね
表現がいけませんでしたが、そのように理解しています

あとひとつ伺いたいのが(アドバイスいただいたことがまだちゃんと理解できたわけではないのでアレですが)、
参照透明性が担保されているとは、(1.アクションを生成する時点までは)副作用がある処理は書くことができない、ということでしょうか
2025/01/10(金) 19:48:40.81ID:N8eMPB8m
>>643 ですが、
このレスはちょっと意味が分かりませんね
実行前なので副作用は怒りようがありませんね
2025/01/10(金) 20:01:13.00ID:X+hiLHcK
>>643-644
そのように理解しています。って本当に理解してるか?

アクションの生成において生成しているのは入出力の指示書みたいなもので入出力自体はない。
こういう入力があったらこういう計算方法でこういう出力をするみたいな手順を生成しているだけ。

なんで参照透明性が担保されているというところでそんな引っかかるんだ?
2025/01/10(金) 20:34:59.37ID:0gelnbg2
>>643 で確認したかったことは次のようなことでした

アクションを生成する段までは副作用なく、同一のプログラムを入力とすれば、かならず同一のアクションが出力されるか
ということでした

それはそうであるように思います
2025/01/10(金) 20:42:16.47ID:X+hiLHcK
同一のプログラムを入力とすればってどういう意味?
前も言ったようにアクションの生成とアクションの実行は別フェーズ。同一のアクションが出力される、というのはどっちのフェーズでのことを言ってんの?
2025/01/10(金) 21:16:13.66ID:0gelnbg2
アクションが出力される、なので 1.です
2025/01/10(金) 21:34:10.26ID:X+hiLHcK
なんか理解しているのかすごい怪しいなぁ。

一応回答しておくと、アクションの生成のフェーズなら参照透明性を保証された純粋関数の計算でしかないから
main文が同じなら当然同じアクションが生成される。
同じプログラムなら生成されるものも同じという意味で。

理解してたらこんな話出てこないと思うんだけど。
2025/01/10(金) 22:49:49.12ID:/2hXYNXu
>>649
重ね重ね、ありがとうございます

理解できているかいなかについては、理解が浅いため、確認のために伺わせていただいています

伝わりづらくて申し訳ありませんでしたが、>>649の内容のような理解で正しいかを確認したかったというのが趣旨でした
簡潔に表現していただいて助かりました
2025/01/13(月) 17:46:46.07ID:uTEEqnKb
あけなしておめでとうございます
去年は多様性がようやく否定され始めた年ですが、
今年はhaskellの純粋主義のやうに分類・隔離・排除躍進の年となるようがんばりましょう
2025/01/15(水) 00:44:26.65ID:O9bWSOqU
マクロな現象には個々人のばらつきを否定する力はない
逆に個人は10回連続でグーを出してみてもたとえば「正規分布に従う」とかなんとかいう法則を反証できない

ミクロとマクロを隔離したのはただの統計学であって純粋でも主義でもない
2025/01/15(水) 05:29:17.90ID:QElBeHY8
誰もいまミクロ・マクロの話なんてしてないぞ
2025/01/21(火) 22:22:46.92ID:QQz8h7YM
雪田の英語版買って読んだ勇者はおらんか?
2025/01/22(水) 01:14:29.67ID:SDQT/604
3万も出してよもうとは思わない。

目次読むとKleisli tripleの節はあるのにKleisli categoryの節がなかったり、なぜかその後にMoggi's theoryが出てきたりと
少なくとも構成があんまりいい感じはしない。
2025/01/22(水) 03:57:21.12ID:ydcqGqD9
まぁ圏論はHaskellやるうえで無駄だしな
657デフォルトの名無しさん
垢版 |
2025/01/23(木) 21:00:49.82ID:j8NlocC3
しかもHaskell自体やるだけ無駄だしな
658デフォルトの名無しさん
垢版 |
2025/02/13(木) 07:10:20.44ID:NHs8kkcw
wikiでghc見たら、中の人MSリサーチにいるのな。
最近C#並みに速くなったと思ったら、そういう事か。
納得。
2025/02/13(木) 13:53:19.78ID:LmH89MFs
暗記系の問題が嫌われるのは答えを隠す意味がないからだが
逆に陰謀論が大人気なのは、隠蔽する動機があるからかもしれない
2025/02/13(木) 19:59:58.08ID:8vmF21CT
>>659
誤爆か?
次から気をつけな
2025/02/13(木) 21:57:13.74ID:FvaixK+o
わざとだろ。
数板に延々スレ違を書き込む基地外がいるが多分そいつと同一。
2025/02/13(木) 22:11:56.50ID:LxUFvhMj
ワードサラダくん数学板にもいるんか
まあいそうな板だな
2025/02/13(木) 23:39:39.86ID:LmH89MFs
有意味な事実と有意味なデマを隔離するのは難しいらしい
だが、真でも偽でもないナンセンスはなぜか瞬時に判断できる
2025/03/19(水) 11:03:50.18ID:JUfTLTVZ
IntSetのsizeがO(1)じゃなくO(n)なのはなぜですか、O(1)で実装できそうなもんですが
2025/03/19(水) 19:45:13.59ID:4qyoYSYb
unionとかで重複要素数えるのが面倒だから必要になるまで数えない
666デフォルトの名無しさん
垢版 |
2025/03/19(水) 20:51:01.02ID:S6mpqhEQ
私は最強ーーすき
667デフォルトの名無しさん
垢版 |
2025/03/19(水) 20:52:16.86ID:S6mpqhEQ
誤爆スマソ。懐メロチャンネルと間違えた
668デフォルトの名無しさん
垢版 |
2025/10/08(水) 08:47:56.03ID:66xUgFQM
int* map(int (*f)(const int), const int* array, const int n){
  int* p = malloc(sizeof(int) * n);
  for(int i = 0; i < n; i++) p[i] = f(array[i]);
  return p;
}

ふむ、メモリ管理が必要な言語が(見かけ上)副作用のない関数を作ろうとしたら配列を返す関数の時点で関数を使った後は必ずメモリの開放が必要になるのか。
開放が必要だから、参照を持つためにポインタへの保存が必須なので、関数の連続適用(関数合成)は絶望的。

これじゃ、GCやRustみたいな仕組みが必要になるわけだ。
2025/10/08(水) 10:40:05.18ID:qRy2t+J8
Cで副作用はいうてらんないね。マルチスレッド、再入可能にするところまで出来れば上出来
2025/10/08(水) 13:07:06.38ID:4LSFWHe4
>>668
30点の理解
2025/10/08(水) 14:05:41.01ID:JTvRYaZp
GC言語はGC使ってる時点で副作用あるやんw
メモリ管理他人任せにしてるだけだ
2025/10/08(水) 17:42:33.77ID:1ctt2fBW
>>671
−30点
673デフォルトの名無しさん
垢版 |
2025/10/08(水) 18:32:01.08ID:66xUgFQM
>>670
100点満点のご高説をどうぞ。
長文になっても良し。

>>671
実は純粋関数型言語の定義は「副作用も含めて参照透明性が破れていない」なのです。(Wiki調べ)
print関数やgetLine関数はどう見ても副作用有るでしょう?
でも、モナドのお陰で参照透明性は破れてないんですよ。
2025/10/08(水) 18:44:02.95ID:N7mcxj5n
副作用は隔離スレへ
2025/10/08(水) 18:45:31.77ID:HFQA1hQ+
なるほどモナドと書き込めばこのスレで副作用の話もできるのですね
2025/10/08(水) 23:41:30.24ID:jkiZK6Mq
>>673
ゴールがわからないので100点のご高説は無理だが30点の理由は説明しといてあげる

C言語という特定の言語実装における制約がメモリ管理が必要な言語全般に対しても当てはまると考えてるのが根本的な間違い

>配列を返す関数の時点で関数を使った後は必ずメモリの開放が必要になるのか。
>>668のコードで(明示的な)メモリ解放が必要になるのはヒープに動的にメモリをアロケートしたからであって配列を返すからではない

C言語では配列がfirst classではないので配列をそのまま返すことは不可能
C言語でも構造体ならfirst classなので配列という概念を表現した構造体を作って静的配列を返すようにすれば(明示的な)メモリ開放は不要
C言語にはないがジェネリック等の抽象化機構を備えた言語であれば静的配列を使って任意長の配列に対するmap関数も書ける

>開放が必要だから、参照を持つためにポインタへの保存が必須
動的にアロケートするものは実行時になるまで必要なメモリサイズがわからないから言語に関係なくポインタ的なものでしか表現しようがない
動的にアロケートしたものだからポインタが必須、ヒープに動的にアロケートしたものだから後で(明示的な)開放が必要なのであって、開放が必要だからポインタへの保存が必須という因果関係ではない
677デフォルトの名無しさん
垢版 |
2025/10/09(木) 02:23:13.64ID:j1OYGPg+
>>676
確かにメモリ管理が必要な手続き型言語全般というのは広げすぎたかもしれない。
静的な配列を関数内で作ってポインタを返す形で作ると関数を抜ける際に配列の寿命が尽きる。
(通常、それを避けるために結果を格納するためのポインタを引数で渡す)

C言語で関数型言語のmap関数みたいな配列を返す関数が作れるか?と考えると動的に作って、使い終わったら解放する形になるのかなと。
ここへの書き込みが長すぎると怒られたので削除したが、構造体で包むという案も考えた。
値渡しだからコピーコストがかさむ。
参照渡しだと生の配列と同じ寿命の問題に突き当たる。
2025/10/09(木) 10:26:59.37ID:DbxsJTmB
>>677
>値渡しだからコピーコストがかさむ。
コンパイラの最適化で不必要なコピーは消える
C言語でもそういうことは当たり前にやってる
2025/10/09(木) 11:59:08.62ID:4MZdWW58
仕様化されてるっけ
コンパイラの実装次第だと怪しい
2025/10/09(木) 17:36:59.11ID:jE8FE7Nk
Cに何を求めてんだよw
2025/10/09(木) 17:53:09.88ID:N3YUsGEr
OS開発ですね。メモリも割り込みも何でも見えてしまい、扱わないといけません
682デフォルトの名無しさん
垢版 |
2025/10/09(木) 18:19:20.69ID:j1OYGPg+
>>678
にゃんと!?
それを押してもいざ実装してみたら
構造体で配列を包む場合、あらかじめ配列の長さを決めないといけなかった。

struct {
    int array[1024];
    int size;
}typedef Array;

この1024とかも余分な分は最適化で無くなるっていうなら10万位要素があっても大丈夫なように1GB位(見かけ上)確保したいが、そうでないなら大体の場合、無駄な領域を確保してることになる。
683デフォルトの名無しさん
垢版 |
2025/10/09(木) 18:28:04.54ID:j1OYGPg+
>>678
ん、まてよ?
最適化で不要なコピーは消えるって言っても、関数プログラミングのmap関数と同じ動きなら、参照元の値は変わったらダメなので参照渡しされたら困るんだが、どんな最適化でコピー(値渡し)で無く、かつ参照渡しでもない状態ってどんな状態?
2025/10/09(木) 19:31:35.47ID:XykzCJ/G
Haskellは遅延評価だからmapが配列を返してると言えるかあやしい

一般的な関数型言語だと末尾再帰で不必要になる値を再利用(上書き)する
あと値が変更されない(immutable)なら参照渡しで共有しても問題ないし
共有するためにimmutableにすると言っても過言ではない
685デフォルトの名無しさん
垢版 |
2025/10/09(木) 19:50:16.02ID:j1OYGPg+
>>684
うん、遅延評価だから基本参照を返してるはず。バード本参照
(なので>>668を書いてみたわけで)

immutableなら

a = [1..4]
b = map (+1) [1..4]
print a
print b

とうコードで

output:
[0,1,2,3,4]
[1,2,3,4,5]

になるはず。
Cで参照を共有すると

[1,2,3,4,5]
[1,2,3,4,5]

という困った表示になってしまう。
というかHaskellでも生のリスト[0..4]とmap (+1) [0..4]は参照を共有してない。
共有してるのは[0..4]だけ。
(むしろ共有してないからこそ「富豪プログラミング」とか言われる)
686デフォルトの名無しさん
垢版 |
2025/10/09(木) 20:01:16.79ID:j1OYGPg+
言ってみればHaskellは新しい参照をどんどん生み出して、不要になった参照はガンガンGCする。
Cはそういうプログラミングには(当たり前だが)向かないし、当たり前にCの方が効率は良い。
人間が書くコードはHaskellみたく数学に近いほど短くなる。
どっちが良いとかじゃなく、何を優先するかという話。
(なのだなぁと、Cでmap関数もどきを書いて再確認した)
2025/10/09(木) 20:33:26.39ID:N3YUsGEr
ループ書こうぜ
2025/10/09(木) 21:58:50.95ID:HS++2zZ0
>>682
「ジェネリック等の抽象化機構を備えた言語であれば〜」のところ全然理解してなかったのな

>>683
言語の仕様上は値渡しだけど実際にわざわざコピーして渡す必要がない状況ならコンパイラが最適化してコピーしないマシンコード(コピーして渡すのと同じ結果になるマシンコード)を生成するという話
異なるレイヤーを混同してることに気づいてくれ

あとHaskellのリストは配列じゃないよ
689デフォルトの名無しさん
垢版 |
2025/10/10(金) 05:32:34.82ID:WzZmvOuY
Haskellを勉強したけど何に使えばいいのか分からない
関数型プログラミングで難しい割に、速度が出ないことがわかっているやっぱり速度は正義だろ
690デフォルトの名無しさん
垢版 |
2025/10/10(金) 07:17:31.85ID:G/tXieG5
>>688
ジェネリックはそのうちC++なりJavaなりで試すけど、まだ試してもいないので…。

最適化の方はもうちょい具体的に教えて欲しいかも。
x = 2 * 100を x = 200にするみたいなのは知ってるけど、あんま詳しくない。
691デフォルトの名無しさん
垢版 |
2025/10/10(金) 07:21:42.77ID:G/tXieG5
>>689
今のHaskellは(中の人がMSに勤め始めてから)C#並みに速くなってるけど、GUIライブラリとか軒並み遅い時代に開発が止まってる…。
しいて言えばYesod使ってWebアプリかな?
Mac(Appleシリコン)版があるからiOSアプリのロジック部分とかも行けそう。
2025/10/10(金) 20:26:02.07ID:OD0KmsJp
【移民】 は努力もせずに日本の豊かさを手に入れる
https://medaka.5ch.net/test/read.cgi/kankon/1759822097/l50
693デフォルトの名無しさん
垢版 |
2025/10/11(土) 22:42:46.58ID:pZv0dAV3
22 template <typename T>
23 vector<T> map(function<T(T)> f, const vector<T> arr){
24 vector<T> temp;
25 for(auto i : arr) temp.push_back(f(i));
26 return temp;
27 }
694デフォルトの名無しさん
垢版 |
2025/10/11(土) 22:43:04.64ID:pZv0dAV3
C++で書いてみた。
今回は値渡しにしたけど、本当に最適化でコピーにならないようにできるのかな…。
そもそもどうやってそれを確認するんだろう?
本当なら参照渡しがほぼ要らなくなるけど。
そして、例によって参照渡しだと>>668やコードこそ書いてないがCで一般的な>>677のカッコ内に書いた(通常、それを避けるために結果を格納するためのポインタを引数で渡す)になる。

コードにするとこう。
(Haskellerなのでmapにしたけど、C++だとmapって連想配列なのね。失敗した…)

void map(vector<int>* input, vector<int>* output);

配列と比べて長さを引数に渡さないで良くなるのと、realocしなくても長さを変更できる点が進化しているが。
レスを投稿する

5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

ニューススポーツなんでも実況