探検
関数型プログラミング言語Haskell Part34
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みたいな仕組みが必要になるわけだ。
int* p = malloc(sizeof(int) * n);
for(int i = 0; i < n; i++) p[i] = f(array[i]);
return p;
}
ふむ、メモリ管理が必要な言語が(見かけ上)副作用のない関数を作ろうとしたら配列を返す関数の時点で関数を使った後は必ずメモリの開放が必要になるのか。
開放が必要だから、参照を持つためにポインタへの保存が必須なので、関数の連続適用(関数合成)は絶望的。
これじゃ、GCやRustみたいな仕組みが必要になるわけだ。
669デフォルトの名無しさん
2025/10/08(水) 10:40:05.18ID:qRy2t+J8 Cで副作用はいうてらんないね。マルチスレッド、再入可能にするところまで出来れば上出来
670デフォルトの名無しさん
2025/10/08(水) 13:07:06.38ID:4LSFWHe4 >>668
30点の理解
30点の理解
671デフォルトの名無しさん
2025/10/08(水) 14:05:41.01ID:JTvRYaZp GC言語はGC使ってる時点で副作用あるやんw
メモリ管理他人任せにしてるだけだ
メモリ管理他人任せにしてるだけだ
672デフォルトの名無しさん
2025/10/08(水) 17:42:33.77ID:1ctt2fBW >>671
−30点
−30点
673デフォルトの名無しさん
2025/10/08(水) 18:32:01.08ID:66xUgFQM674デフォルトの名無しさん
2025/10/08(水) 18:44:02.95ID:N7mcxj5n 副作用は隔離スレへ
675デフォルトの名無しさん
2025/10/08(水) 18:45:31.77ID:HFQA1hQ+ なるほどモナドと書き込めばこのスレで副作用の話もできるのですね
676デフォルトの名無しさん
2025/10/08(水) 23:41:30.24ID:jkiZK6Mq >>673
ゴールがわからないので100点のご高説は無理だが30点の理由は説明しといてあげる
C言語という特定の言語実装における制約がメモリ管理が必要な言語全般に対しても当てはまると考えてるのが根本的な間違い
>配列を返す関数の時点で関数を使った後は必ずメモリの開放が必要になるのか。
>>668のコードで(明示的な)メモリ解放が必要になるのはヒープに動的にメモリをアロケートしたからであって配列を返すからではない
C言語では配列がfirst classではないので配列をそのまま返すことは不可能
C言語でも構造体ならfirst classなので配列という概念を表現した構造体を作って静的配列を返すようにすれば(明示的な)メモリ開放は不要
C言語にはないがジェネリック等の抽象化機構を備えた言語であれば静的配列を使って任意長の配列に対するmap関数も書ける
>開放が必要だから、参照を持つためにポインタへの保存が必須
動的にアロケートするものは実行時になるまで必要なメモリサイズがわからないから言語に関係なくポインタ的なものでしか表現しようがない
動的にアロケートしたものだからポインタが必須、ヒープに動的にアロケートしたものだから後で(明示的な)開放が必要なのであって、開放が必要だからポインタへの保存が必須という因果関係ではない
ゴールがわからないので100点のご高説は無理だが30点の理由は説明しといてあげる
C言語という特定の言語実装における制約がメモリ管理が必要な言語全般に対しても当てはまると考えてるのが根本的な間違い
>配列を返す関数の時点で関数を使った後は必ずメモリの開放が必要になるのか。
>>668のコードで(明示的な)メモリ解放が必要になるのはヒープに動的にメモリをアロケートしたからであって配列を返すからではない
C言語では配列がfirst classではないので配列をそのまま返すことは不可能
C言語でも構造体ならfirst classなので配列という概念を表現した構造体を作って静的配列を返すようにすれば(明示的な)メモリ開放は不要
C言語にはないがジェネリック等の抽象化機構を備えた言語であれば静的配列を使って任意長の配列に対するmap関数も書ける
>開放が必要だから、参照を持つためにポインタへの保存が必須
動的にアロケートするものは実行時になるまで必要なメモリサイズがわからないから言語に関係なくポインタ的なものでしか表現しようがない
動的にアロケートしたものだからポインタが必須、ヒープに動的にアロケートしたものだから後で(明示的な)開放が必要なのであって、開放が必要だからポインタへの保存が必須という因果関係ではない
677デフォルトの名無しさん
2025/10/09(木) 02:23:13.64ID:j1OYGPg+ >>676
確かにメモリ管理が必要な手続き型言語全般というのは広げすぎたかもしれない。
静的な配列を関数内で作ってポインタを返す形で作ると関数を抜ける際に配列の寿命が尽きる。
(通常、それを避けるために結果を格納するためのポインタを引数で渡す)
C言語で関数型言語のmap関数みたいな配列を返す関数が作れるか?と考えると動的に作って、使い終わったら解放する形になるのかなと。
ここへの書き込みが長すぎると怒られたので削除したが、構造体で包むという案も考えた。
値渡しだからコピーコストがかさむ。
参照渡しだと生の配列と同じ寿命の問題に突き当たる。
確かにメモリ管理が必要な手続き型言語全般というのは広げすぎたかもしれない。
静的な配列を関数内で作ってポインタを返す形で作ると関数を抜ける際に配列の寿命が尽きる。
(通常、それを避けるために結果を格納するためのポインタを引数で渡す)
C言語で関数型言語のmap関数みたいな配列を返す関数が作れるか?と考えると動的に作って、使い終わったら解放する形になるのかなと。
ここへの書き込みが長すぎると怒られたので削除したが、構造体で包むという案も考えた。
値渡しだからコピーコストがかさむ。
参照渡しだと生の配列と同じ寿命の問題に突き当たる。
678デフォルトの名無しさん
2025/10/09(木) 10:26:59.37ID:DbxsJTmB679デフォルトの名無しさん
2025/10/09(木) 11:59:08.62ID:4MZdWW58 仕様化されてるっけ
コンパイラの実装次第だと怪しい
コンパイラの実装次第だと怪しい
680デフォルトの名無しさん
2025/10/09(木) 17:36:59.11ID:jE8FE7Nk Cに何を求めてんだよw
681デフォルトの名無しさん
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位(見かけ上)確保したいが、そうでないなら大体の場合、無駄な領域を確保してることになる。
にゃんと!?
それを押してもいざ実装してみたら
構造体で配列を包む場合、あらかじめ配列の長さを決めないといけなかった。
struct {
int array[1024];
int size;
}typedef Array;
この1024とかも余分な分は最適化で無くなるっていうなら10万位要素があっても大丈夫なように1GB位(見かけ上)確保したいが、そうでないなら大体の場合、無駄な領域を確保してることになる。
683デフォルトの名無しさん
2025/10/09(木) 18:28:04.54ID:j1OYGPg+ >>678
ん、まてよ?
最適化で不要なコピーは消えるって言っても、関数プログラミングのmap関数と同じ動きなら、参照元の値は変わったらダメなので参照渡しされたら困るんだが、どんな最適化でコピー(値渡し)で無く、かつ参照渡しでもない状態ってどんな状態?
ん、まてよ?
最適化で不要なコピーは消えるって言っても、関数プログラミングのmap関数と同じ動きなら、参照元の値は変わったらダメなので参照渡しされたら困るんだが、どんな最適化でコピー(値渡し)で無く、かつ参照渡しでもない状態ってどんな状態?
684デフォルトの名無しさん
2025/10/09(木) 19:31:35.47ID:XykzCJ/G Haskellは遅延評価だからmapが配列を返してると言えるかあやしい
一般的な関数型言語だと末尾再帰で不必要になる値を再利用(上書き)する
あと値が変更されない(immutable)なら参照渡しで共有しても問題ないし
共有するためにimmutableにすると言っても過言ではない
一般的な関数型言語だと末尾再帰で不必要になる値を再利用(上書き)する
あと値が変更されない(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]だけ。
(むしろ共有してないからこそ「富豪プログラミング」とか言われる)
うん、遅延評価だから基本参照を返してるはず。バード本参照
(なので>>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関数もどきを書いて再確認した)
Cはそういうプログラミングには(当たり前だが)向かないし、当たり前にCの方が効率は良い。
人間が書くコードはHaskellみたく数学に近いほど短くなる。
どっちが良いとかじゃなく、何を優先するかという話。
(なのだなぁと、Cでmap関数もどきを書いて再確認した)
687デフォルトの名無しさん
2025/10/09(木) 20:33:26.39ID:N3YUsGEr ループ書こうぜ
688デフォルトの名無しさん
2025/10/09(木) 21:58:50.95ID:HS++2zZ0689デフォルトの名無しさん
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にするみたいなのは知ってるけど、あんま詳しくない。
ジェネリックはそのうち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アプリのロジック部分とかも行けそう。
今のHaskellは(中の人がMSに勤め始めてから)C#並みに速くなってるけど、GUIライブラリとか軒並み遅い時代に開発が止まってる…。
しいて言えばYesod使ってWebアプリかな?
Mac(Appleシリコン)版があるからiOSアプリのロジック部分とかも行けそう。
692デフォルトの名無しさん
2025/10/10(金) 20:26:02.07ID:OD0KmsJp693デフォルトの名無しさん
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 }
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しなくても長さを変更できる点が進化しているが。
今回は値渡しにしたけど、本当に最適化でコピーにならないようにできるのかな…。
そもそもどうやってそれを確認するんだろう?
本当なら参照渡しがほぼ要らなくなるけど。
そして、例によって参照渡しだと>>668やコードこそ書いてないがCで一般的な>>677のカッコ内に書いた(通常、それを避けるために結果を格納するためのポインタを引数で渡す)になる。
コードにするとこう。
(Haskellerなのでmapにしたけど、C++だとmapって連想配列なのね。失敗した…)
void map(vector<int>* input, vector<int>* output);
配列と比べて長さを引数に渡さないで良くなるのと、realocしなくても長さを変更できる点が進化しているが。
レスを投稿する
ニュース
- 拳銃24丁を中国から日本国内に輸入した疑い 中国人の46歳の男逮捕 1丁約3000円で販売 [七波羅探題★]
- サッカーW杯、日本代表戦は地上波で放送へ DAZNは全試合配信 [鉄チーズ烏★]
- 水深2mのホテルプールで大学生溺死、監視員なし 8千万円賠償命令 [蚤の市★]
- 有名な買い取り店にCD5000枚を持ち込んで売却した谷原章介、買い取り価格に後悔し30分後に戻るも…「ショックだった」 [muffin★]
- 【文春】AKB48『紅白歌合戦』出場へ! 前田敦子&大島優子が限定復活! 『ヘビロテ』など黄金期メドレー披露 神7の多くが出場 [冬月記者★]
- 渡邊渚『日本は男性の性欲に甘い国』「女性をどうやって騙して呼び出すか力説するおじさん」日本で多発する性的搾取について思うこと ★3 [Ailuropoda melanoleuca★]
- 👊👊👊👊🏡👊👊👊👊
- 天音かなたさん、たった一人でホロライブの時価総額を65億吹き飛ばすwwwww
- 【高市速報】日本企業、台湾から機密半導体技術を盗んだ罪で起訴 [237216734]
- 【悲報】日本人、ガチでコメ離れしてしまいJAと農家さんが焦りまくるwww「お米券で高い米を買ってもらえるようにしてほしい」 [793117252]
- 【画像】懲役64年で出所した爺さん(91)ガチでヤバすぎる [977261419]
- 【悲報】人気VTuberの天音かなたさん、ホロライブ卒業★4 [485689427]
