1 名前:デフォルトの名無しさん mailto:sage [2007/08/05(日) 14:49:54 ] 関数型言語MLについて語るスレッドです。 MLは、確固とした理論的背景を持つ言語でありながら、 現実的なソフトの開発にも使用できる実用性を備えた言語です。 また、プログラミングの初心者が最初に学習する言語としても優れています。 総本山 Standard ML www.smlnj.org/ Objective Caml caml.inria.fr/ocaml/ 前スレ 関数型言語ML(SML, OCaml, etc.), Part 4 pc11.2ch.net/test/read.cgi/tech/1133003340/
326 名前:デフォルトの名無しさん mailto:sage [2008/05/12(月) 06:56:30 ] >>325 どうも
327 名前:デフォルトの名無しさん mailto:sage [2008/05/12(月) 13:01:46 ] 代数データ型があるかどうかは、関数型かどうかを左右しない。 ただ今時の関数型言語に代数データ型を持っているのが多いというだけ。
328 名前:デフォルトの名無しさん mailto:sage [2008/05/12(月) 17:48:27 ] 関数型言語という言葉に明確な定義が無い以上、ある言語が関数型かどうかは 「典型的な関数型言語」にどれくらい似ているかという尺度で測る他無いんじゃね?
329 名前:デフォルトの名無しさん mailto:sage [2008/05/12(月) 19:25:20 ] あなたがそう思うものが関数型言語です。 ただし、他人の同意を得られるとはかぎりません。
330 名前:デフォルトの名無しさん mailto:sage [2008/05/12(月) 20:02:47 ] 無意味なレスしてんなよ noob
331 名前:デフォルトの名無しさん mailto:sage [2008/05/12(月) 23:17:55 ] >>319 逆だよ。 F#は製品化が決まって現在仕様の取りまとめ中。
332 名前:デフォルトの名無しさん mailto:sage [2008/05/13(火) 08:09:27 ] >>328 そんなわけないだろw 代数的データ型があるかどうかは、関数型言語かどうかの尺度にはならない。 >>331 あそこは仕様=実装って会社でしょ。 V0.9的な仕様作ってそれでおしまい。
333 名前:デフォルトの名無しさん mailto:sage [2008/05/13(火) 09:58:17 ] もともと仕様と実装が同じ言語から派生した言語に何を求めるのか.
334 名前:デフォルトの名無しさん mailto:sage [2008/05/13(火) 14:55:39 ] >>332 じゃあ、何が尺度になるの?もちろん、代数的データ型*さえあれば*関数型言語 だとは言うつもりは無いけど、関数型言語の定義なんて人によってかなり曖昧な わけだ。MLとかHaskellとかのまず間違いなく関数型言語だと認定してもらえる言語と どれだけ同じ機能を持っているかで比較するしか無いんじゃない?
335 名前:デフォルトの名無しさん mailto:sage [2008/05/13(火) 16:08:24 ] プログラムが参照の透明性のある関数だけで構成されていること でいいんじゃない?
336 名前:デフォルトの名無しさん mailto:sage [2008/05/13(火) 16:54:44 ] stateがないってんじゃ駄目なの? monadでstateは扱えるけど、 stateがあるわけじゃないよね。 stateがないってことを厳密にいうと、 「ある時にy=f(x)ならば、どんな時でもy=f(x)」ってことでいいのかな?
337 名前:デフォルトの名無しさん mailto:sage [2008/05/13(火) 17:17:45 ] > プログラムが参照の透明性のある関数だけで構成されていること じゃあ、MLやOCamlはNGじゃん。ref型があるわけだから。
338 名前:デフォルトの名無しさん mailto:sage [2008/05/13(火) 17:54:46 ] >>337 関数だけで構成されていること でいいんじゃない?
339 名前:デフォルトの名無しさん mailto:sage [2008/05/13(火) 20:49:17 ] >>338 それだとHaskellすらNGだな
340 名前:デフォルトの名無しさん mailto:sage [2008/05/13(火) 20:56:34 ] C++ だって関数型言語なのに!
341 名前:デフォルトの名無しさん mailto:sage [2008/05/13(火) 21:44:13 ] >>340 ないないそれはない
342 名前:デフォルトの名無しさん mailto:sage [2008/05/13(火) 21:47:37 ] それ有名なネタだよ
343 名前:デフォルトの名無しさん mailto:sage [2008/05/13(火) 21:49:08 ] マクロとテンプレートを思いっきり使えば それらしいコードは書けるかもしれない。
344 名前:デフォルトの名無しさん [2008/05/14(水) 07:36:28 ] omake はええぞ。omake -P を知ったらやめられん。
345 名前:デフォルトの名無しさん mailto:sage [2008/05/14(水) 11:58:34 ] Boost おそるべし
346 名前:デフォルトの名無しさん mailto:sage [2008/05/14(水) 19:10:58 ] でもないw
347 名前:デフォルトの名無しさん mailto:sage [2008/05/17(土) 09:53:43 ] 今日職場で出た話題。 以下のOCamlコードが最終行でエラーには * ならなさそうで、 * でもなりそうで、 * でもやっぱりならない理由と、 この問題の意図を考えなさい。 let id x = x let unify x y = if true then x else y let v = id `A let _ = unify v `B let _ = match v with | `A -> ()
348 名前:デフォルトの名無しさん [2008/05/17(土) 10:31:08 ] なんでエラーになりそうなのかわからない。
349 名前:デフォルトの名無しさん mailto:sage [2008/05/17(土) 11:19:41 ] >| `A -> () なんかAAぽい
350 名前:デフォルトの名無しさん mailto:sage [2008/05/17(土) 13:48:50 ] >>349 怒ってため息をついてるね。w
351 名前:デフォルトの名無しさん mailto:sage [2008/05/17(土) 15:38:52 ] 標準で関数型プログラミングをサポートする言語=関数型言語じゃね 標準のSTLだけだと関数型プログラミングは厳しいのでC++は入らないと思う
352 名前:デフォルトの名無しさん mailto:sage [2008/05/17(土) 17:10:34 ] Q. 関数型プログラミングとは? A. 関数型言語が標準でサポートしているプログラミング
353 名前:デフォルトの名無しさん mailto:sage [2008/05/17(土) 21:04:26 ] 相互再帰ですか
354 名前:デフォルトの名無しさん mailto:sage [2008/05/17(土) 21:44:22 ] >>353 無限に再帰してて、止まらないわけですね、わかります。
355 名前:デフォルトの名無しさん mailto:sage [2008/05/17(土) 22:08:01 ] 再帰なんて簡単だお。
356 名前:デフォルトの名無しさん mailto:sage [2008/05/17(土) 22:32:21 ] >>347 >今日職場で出た話題。 どこの職場ですか?日本ですか?
357 名前:デフォルトの名無しさん mailto:sage [2008/05/18(日) 00:30:58 ] let id x = xと let v = id `Aと let _ = match v with | `A -> () だけみれば`Aと`Aだからエラーにならなそうで let unify x y = if true then x else y let _ = unify v `B もみるとxとyが同じ型じゃないとエラーで`Aと`Bだからエラーになりそう でも多相バリアントだからエラーにならないみたいな。 なんか問題がわるいな
358 名前:デフォルトの名無しさん mailto:sage [2008/05/18(日) 00:32:16 ] 357は>>347 へのレス 書き忘れたorz
359 名前:デフォルトの名無しさん mailto:sage [2008/05/18(日) 01:16:05 ] type 'a 関数型言語 = { 変数 : 参照透過; 関数 : 高階; 型 : 代数的; } constraint 'a = 多相
360 名前:デフォルトの名無しさん mailto:sage [2008/05/18(日) 08:22:31 ] >>351 個人的にはSTLがどれほど充実しようが、後付けのクロージャが qsort に渡せ ない時点で除外したい。箱庭の中だけで関数プログラミングをサポートしても、 その言語が関数型とは言い難い。どんな言語でも関数型言語を「実装」する事 は出来るので。
361 名前:デフォルトの名無しさん mailto:sage [2008/05/18(日) 12:09:28 ] std::sort に渡せりゃそれで十分じゃん。
362 名前:デフォルトの名無しさん mailto:sage [2008/05/18(日) 16:41:50 ] qsortのほうがずいぶん遅いしね
363 名前:デフォルトの名無しさん mailto:sage [2008/05/18(日) 16:49:38 ] >>362 プラットフォームによるとqsortの方が団地に早かったりするんですが どのようなプラットフォームでお仕事をしておいででしょうか?
364 名前:デフォルトの名無しさん mailto:sage [2008/05/18(日) 17:12:28 ] windows。それ、最適化してんの?
365 名前:デフォルトの名無しさん mailto:sage [2008/05/18(日) 17:24:49 ] >>36 qsort() の呼び出しでは関数ポインタの呼び出しが多いから、インラインで置換するコードには負けてしまうと思います。
366 名前:デフォルトの名無しさん mailto:sage [2008/05/18(日) 18:25:41 ] >>363 プラットフォームって、インライン最適化もできない糞コンパイラを使えばって話か?
367 名前:デフォルトの名無しさん mailto:sage [2008/05/18(日) 18:46:20 ] あるいはstd::sortに関数ポインタを渡してるとか
368 名前:デフォルトの名無しさん mailto:sage [2008/05/18(日) 20:41:28 ] おもしろいな。 関数呼び出しコスト以上に速くなる?
369 名前:デフォルトの名無しさん mailto:sage [2008/05/19(月) 07:57:36 ] >>361 qsort はただの例。ライブラリの形で別言語を実装しておいて関数型でございっ てのが気に入らないってだけ。関数ポインタを要求している所に渡したり、新 しい関数ポインタのインスタンスを実行時に作れないと。
370 名前:デフォルトの名無しさん mailto:sage [2008/05/19(月) 08:58:50 ] > ライブラリの形で別言語を実装しておいて 言語内の機能で実装しているんだぜ?
371 名前:デフォルトの名無しさん mailto:sage [2008/05/19(月) 21:49:06 ] クロージャはファーストクラスじゃないとね
372 名前:デフォルトの名無しさん mailto:sage [2008/05/19(月) 22:47:50 ] >>370 それいうとあらゆる言語が関数型を名乗れるから。
373 名前:デフォルトの名無しさん mailto:sage [2008/05/19(月) 23:02:44 ] >>370 それいったらアセンブラだって関数型だろwww
374 名前:デフォルトの名無しさん mailto:sage [2008/05/20(火) 06:52:47 ] つまらんんこと言っとらんでコード書け。
375 名前:デフォルトの名無しさん mailto:sage [2008/05/20(火) 08:27:19 ] C++のboost:lambdaみたいなのを、 言語の本来の機能で実装できるのってないんじゃねえ?
376 名前:デフォルトの名無しさん mailto:sage [2008/05/20(火) 10:04:38 ] >>375 boost.lambda 見てないんだけど Lisp のマクロ、R6RS のマクロでも無理?
377 名前:デフォルトの名無しさん mailto:sage [2008/05/20(火) 11:19:19 ] 関数型は最初からラムダ式があるから必要ないのでは。 zip(list1, list2, _1 + _2) //←こんな感じ。
378 名前:デフォルトの名無しさん mailto:sage [2008/05/20(火) 17:44:55 ] Boostはポリシーによるプログラミングができる (lambda (lambda (funcname)) (funcname ...)) ↑こんなイメージ。これはLISPだったらマクロなしだと実現不可能じゃない? 型システムが閉じてないことが前提だから OcamlやF#ではこれ、実現不可能だと思う //ちら裏:自分はBoostが関数型言語やろうと思ったきっかけ
379 名前:デフォルトの名無しさん mailto:sage [2008/05/20(火) 17:52:12 ] >>378 マクロ書けばええやん? 言語本来の機能でっせ、Lisp のマクロは…
380 名前:デフォルトの名無しさん mailto:sage [2008/05/20(火) 18:56:16 ] >>378 >LISPだったらマクロなしだと その前提が間違い。何の為の S 式だか。
381 名前:デフォルトの名無しさん mailto:sage [2008/05/20(火) 22:14:56 ] すまん、今の流れでマクロなしってのは間違ってるなw しかし、マクロありでもポリシーによるプログラミングはLISPでは不可能なんじゃね? ここでS式が出てくるのはなぜ? 静的な型を持つ言語じゃないとコンパイル時型チェックの利点はなくなるし 単なるダックタイピングになってしまう 現時点では閉じていない多態かつ静的な言語って 俺が知る限りC++ぐらいしかないけど他にあるのかな Template Haskellとかどうなんだろ
382 名前:デフォルトの名無しさん mailto:sage [2008/05/20(火) 22:19:20 ] >>381 >ここでS式が出てくるのはなぜ? 興味無いくせに聞くなよ
383 名前:デフォルトの名無しさん mailto:sage [2008/05/20(火) 22:26:20 ] >>381 declare すりゃいい話だし、元気があればコンパイラ書き換えれば OK 型推論でも何でもできるんじゃないか?
384 名前:デフォルトの名無しさん mailto:sage [2008/05/20(火) 22:28:55 ] ああ、コンパイラ作るのか・・その発想はなかったわw
385 名前:デフォルトの名無しさん mailto:sage [2008/05/21(水) 21:52:19 ] >>384 つか, 処理系自体にシンタックスパーサからコンパイラまで含んでて そいつらを自前の定義に書き換え可能な言語相手に何を戦ってるんだか
386 名前:デフォルトの名無しさん mailto:sage [2008/05/21(水) 23:06:06 ] >>378 すまんが、このコードで何をしてるのか参考までに教えてくれ・・・ >>385 C++に脳を冒されて、そんな言語が存在することを知るよしもないんだろう
387 名前:デフォルトの名無しさん mailto:sage [2008/05/22(木) 05:23:56 ] >>339 いや、セーフだろ
388 名前:デフォルトの名無しさん mailto:sage [2008/05/22(木) 07:28:36 ] 職場で出た話題。 O'Caml で、v == v は真なのに v = v は偽な値 v は存在するか。
389 名前:デフォルトの名無しさん mailto:sage [2008/05/22(木) 08:16:39 ] NaN
390 名前:デフォルトの名無しさん mailto:sage [2008/05/22(木) 21:55:52 ] >>375 >静的な型を持つ言語じゃないとコンパイル時型チェックの利点はなくなるし OCamlは型推論で静的な型が付くからC++並にコンパイル時型チェック働くよ 型変換がらみのバグ出づらい分むしろ安全だと思うけど。 (* てかboost:lambdaコンパイル遅すぎ *)
391 名前:デフォルトの名無しさん mailto:sage [2008/05/22(木) 23:38:28 ] >>390 OCAMLだとこれに相当することができない(STLC<U>が定義済みの場合だけOCamlでも可能) C++では定義済みかどうかは関係なく宣言できる STLライクなデータに対する探索コード template <template <typename T> class STLC,typename U,typename R> bool has_data(STLC<U>&data,const R&value){ typename STLC<U>::iterator it = std::find(data.begin(),data.end(),value); if(it!=data.end())return true; else return false; }
392 名前:デフォルトの名無しさん mailto:sage [2008/05/23(金) 00:30:15 ] begin(data)がイテレータ関数を戻すなら find(b,v)はdataの型と関係なく定義出来る (イテレータ関数の型には影響をうける) クロージャ使えるって忘れてない?
393 名前:デフォルトの名無しさん mailto:sage [2008/05/23(金) 01:10:33 ] >>391 > 宣言できる 「定義できる」かな? 宣言ももちろんできるけど。
394 名前:デフォルトの名無しさん mailto:sage [2008/05/23(金) 01:17:03 ] 念のため言っておくけど、上はあくまでどうしてもイテレータ使いたいならの話 リストは、|でパターンマッチして再帰でグルグルが普通
395 名前:デフォルトの名無しさん mailto:sage [2008/05/23(金) 01:22:07 ] 要は先に定義が必要だったりはしないので、391は間違ってると思われ
396 名前:デフォルトの名無しさん mailto:sage [2008/05/23(金) 01:39:44 ] >>391 の例自体は不適切かもしれんが、C++のテンプレートにできて他の殆どの言語にできないことがあるのは事実だよ C++のテンプレートの顕著な特徴は ・型検査と名前解決の一部がインスタンス化まで遅延される ・特殊化(テンプレート引数に対するパターンマッチ)ができる で、メジャーな言語でこれを備えてるのはC++の他にはDくらいしかないはず
397 名前:デフォルトの名無しさん mailto:sage [2008/05/23(金) 01:55:42 ] SFINAE(Substitution Failure Is Not An Error) en.wikipedia.org/wiki/Substitution_failure_is_not_an_error
398 名前:デフォルトの名無しさん mailto:sage [2008/05/23(金) 01:59:04 ] >>396 取り敢えず CL はどっちも出来るな
399 名前:デフォルトの名無しさん mailto:sage [2008/05/23(金) 02:06:14 ] >>398 良く分からん CLだと引数の型が確定するのは実行時だから、テンプレートみたいなことはやりようが無いんじゃね?
400 名前:デフォルトの名無しさん mailto:sage [2008/05/23(金) 02:12:17 ] GF じゃダメなん?
401 名前:デフォルトの名無しさん mailto:sage [2008/05/23(金) 02:17:12 ] GFって総称関数のこと? それならやっぱり実行時ディスパッチだからテンプレートとは比較できないだろ
402 名前:デフォルトの名無しさん mailto:sage [2008/05/23(金) 04:48:43 ] >>397 Boostじゃ結構使われてるけど英語しか記事無いのか
403 名前:デフォルトの名無しさん mailto:sage [2008/05/23(金) 08:11:36 ] GFってgeneric functionのことだと思うけど、それだと >>401 の書いてるように、実行時の型に基づくディスパッチだから、 コンパイル時にディスパッチが行われるC++のテンプレートの特殊化 とは全然違うでしょ
404 名前:デフォルトの名無しさん mailto:sage [2008/05/23(金) 08:21:47 ] 何で同じ事を2度書く?
405 名前:デフォルトの名無しさん mailto:sage [2008/05/23(金) 08:48:42 ] >>403 packageとcompileで頑張れば、 同じようなものを作れないこともないなあ。 おもしろいかもね。SFINAEはCLOSっぽいね。 まあC++だって総称関数族だから当たり前か。
406 名前:デフォルトの名無しさん mailto:sage [2008/06/02(月) 14:56:29 ] patter match で、 let a = "hoge" in match a with a -> "this is hoge" | "hage" -> "this is hage" | _ -> "other" みたいにして、a を "hoge" としてマッチさせることが出来ないのはどうしてなの
407 名前:デフォルトの名無しさん mailto:sage [2008/06/02(月) 15:25:34 ] パタンに変数参照を書けないから。 パタン中に変数書くときは束縛になるじゃん。
408 名前:デフォルトの名無しさん mailto:sage [2008/06/02(月) 15:37:05 ] あ、そうか。束縛と区別できないのか。 ありがとう でもグローバルに識別子を持っているとき 例えば root_user_name = "hoge" とかあるとして 直接 "hoge" はタイプしたくない場合 match user_name with eval(root_user_name) -> "root user" | _ -> "normal user" とか書きたくなるんだよね 単純なときは if else だけど、複雑なときに書きたくなる
409 名前:デフォルトの名無しさん mailto:sage [2008/06/02(月) 19:00:31 ] つ whenキーワード
410 名前:デフォルトの名無しさん [2008/06/02(月) 19:56:37 ] match user_name with | user when user=root_user_name -> "this is root user" | "hage" -> "this is hage" | _ -> "other" で合ってる?
411 名前:デフォルトの名無しさん mailto:sage [2008/06/02(月) 20:30:39 ] つ if
412 名前:デフォルトの名無しさん mailto:sage [2008/06/03(火) 00:08:07 ] >409 ありがとー 知らなかった すげー恥ずかしい
413 名前:デフォルトの名無しさん mailto:sage [2008/06/03(火) 02:56:54 ] >>412 かじりかけじゃしょうがないと思うからがんばれ。
414 名前:デフォルトの名無しさん mailto:sage [2008/06/05(木) 08:27:09 ] パターンマッチにパターンじゃなくて式を書いちゃうのは初心者にはよくあること。 入門書は振れるべきかもわからんね。
415 名前:デフォルトの名無しさん mailto:sage [2008/06/05(木) 11:13:11 ] つ 入門OCaml
416 名前:デフォルトの名無しさん mailto:sage [2008/06/05(木) 19:44:14 ] 軸がぶれている
417 名前:デフォルトの名無しさん mailto:sage [2008/06/07(土) 10:41:42 ] 質問です、リストの文字を全部つなげるとき List.fold_left (^) "" ["1"; "2"; "3"] とか書くとするじゃないですか でも例えばちょこっと関数を間に挟みたいとき、 let conv x = x ^ "!!" in List.fold_left (fun a b -> a ^ (conv b)) "" ["1"; "2"; "3"] とか書くのって違うのかなとか思ってるんですよ (fun a b ->a ^ (conv b)) の部分をもっとこう関数の合成みたいな感じで短く書く方法ってないですかね
418 名前:デフォルトの名無しさん mailto:sage [2008/06/07(土) 12:19:57 ] 十分簡潔に書けていると思う。わかりやすいし。 なぜそんなに短さにこだわる?
419 名前:デフォルトの名無しさん mailto:sage [2008/06/07(土) 12:31:55 ] 質問の趣旨とずれているが、そもそも (^) を fold するのはお勧めできない。 文字列コピーが多すぎるから。String.concat とか、 Buffer を使うべし。 上の例は、 String.concat "" (List.map conv ["1"; "2"; "3"]) これで十分だろう。(^) を使うなら417で十分。無理に短く書いて喜ぶ言語ではない。
420 名前:デフォルトの名無しさん mailto:sage [2008/06/07(土) 12:36:50 ] ,,,,,,,,,,,,,,,,,,,,,,,,,, /": : : : : : : : \ /-─-,,,_: : : : : : : : :\ / '''-,,,: : : : : : : :i /、 /: : : : : : : : i ________ r-、 ,,,,,,,,,,、 /: : : : : : : : : :i / L_, , 、 \: : : : : : : : :i / λ抽象したら /●) (●> |: :__,=-、: / < 負けかなと思ってる l イ '- |:/ tbノノ \ l ,`-=-'\ `l ι';/ \ ヽトェ-ェェ-:) -r'  ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ヾ=-' / / ____ヽ::::... / ::::| / ̄ ::::::::::::::l `──'''' :::|
421 名前:デフォルトの名無しさん mailto:sage [2008/06/07(土) 14:08:51 ] >>417 俺だったら先にmapする
422 名前:デフォルトの名無しさん mailto:sage [2008/06/07(土) 14:42:08 ] 俺はconvを2引数にしてこんな感じにするかな List.fold_left conv "1" ["2"; "3"]
423 名前:デフォルトの名無しさん mailto:sage [2008/06/07(土) 21:29:56 ] ありがとうございました Buffer は知ってたけど、String.concat は知りませんでした map 先にやって、String.concat で書くことにします
424 名前:デフォルトの名無しさん mailto:sage [2008/06/07(土) 23:34:58 ] OCamlでファイルIOするときUnix.lseekとかが file_descr -> int -> seek_command -> int でintで足りない場合が多々あるかと思うのですが、 皆さんは大きなファイルのIOをするときはどうしてますか? オフセットの計算とかも Int64.add pos (Int64.mul index 4L) みたいにしてやってますか?
425 名前:デフォルトの名無しさん mailto:sage [2008/06/08(日) 01:20:52 ] Unix.LargeFile おまいら、ライブラリ関数で迷ったらまず .mli 読むか、grep するか、 ocamlbrowser でも使えよな。
426 名前:デフォルトの名無しさん mailto:sage [2008/06/08(日) 01:34:33 ] >>425 おお、ありがとうございます!