[表示 : 全て 最新50 1-99 101- 201- 301- 401- 2chのread.cgiへ]
Update time : 05/09 13:54 / Filesize : 121 KB / Number-of Response : 478
[このスレッドの書き込みを削除する]
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧] [類似スレッド一覧]


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

【.NET】F#について語れ【OCAML】



1 名前:デフォルトの名無しさん mailto:sage [2007/08/02(木) 14:03:05 ]
MSResearchから出てきた.NETで使える関数型言語のひとつF#
OCAMLの流れを汲むこの言語、いろいろと面白そうなことができそう。
まだまだ英語の情報しかないこの言語について、幅広く語れ。

research.microsoft.com/fsharp/fsharp.aspx

427 名前:デフォルトの名無しさん mailto:sage [2009/02/07(土) 23:47:23 ]
関数を表す型を定義して、定数関数を定義しようとしたのですが
型からは関数とわかっていても、関数のようには呼び出せませんでした。

以下のようなことを実現するのは難しいのでしょうか?

type FUNC<'arg1,'result> = F of ('arg1 -> 'result);;
F ((+)1);; //使用例1
F (+);; //使用例2
//ここでエラー
let apply1 (f:FUNC<int,int>) = f 1;;

//apply1 ((+)1)、などとしたい

欲を言えば、FUNC型からarg1やresultの型を取り出すような
プログラムも書きたい・・


428 名前:デフォルトの名無しさん mailto:sage [2009/02/08(日) 00:47:21 ]
型と関数を混同してるような
というか、なんかいろいろ勘違いしてそうに見える

> apply1 ((+)1)、などとしたい
で、一体なにをしたいの?その式を評価して得るものはなに?
まずはその式の「型」を教えてくれないとなんともアドバイスできない

いちおーエスパーしとくとこんなんか?

let apply1 f x = f x
let f = apply1 ((+) 1)
f 2 // val it : int = 3

もしなにか Union Types を使わにゃならんような
理由があるんだったなら教えてほしい

429 名前:デフォルトの名無しさん mailto:sage [2009/02/08(日) 02:00:06 ]
ご回答ありがとうございます。
おっしゃるとおり、自分でもたぶん型と関数の違いがあまりわかってないと思います^^;

上の質問をした経緯です
最終的にやりたいことは、let recを用いずにYコンビネータを書きたい
しかし、F#では、次のような呼び出しは型情報が∞ループして決定できない
 let fact self n = if n=1 then 1 else n * ((self self) (n-1)) in fact fact 10;;
そこで、まずは、再帰的なデータ型を定義して用い、上記のような呼び出しを通るようにしたい
(再帰的に'aを'a->'bに置き換えるような型)

しかし、再帰的なデータ型とか、あまりプログラミング経験がないので
型情報を扱うプログラムからまず取り組むことにしたが、つまづいた、とう状況です

上のプログラムですが、次のようにするとコンパイルは通ります。
let apply1 f:FUNC<int,int> = f 1;;
val apply1 : (int -> FUNC<int,int>) -> FUNC<int,int>
しかし、自分が求めた型は
val apply1 : FUNC<int,int> -> int
なのですが、なぜこうなるのかはさっぱりわかってません


430 名前:デフォルトの名無しさん mailto:sage [2009/02/08(日) 08:51:24 ]
MLでYコンビネータを書く話なら、↓の最後にコードが載ってる
私には内容がさっぱり理解できないので、参考になるかどうかは分からんが

ttp://www.kurims.kyoto-u.ac.jp/~hassei/selfref2006.pdf

431 名前:デフォルトの名無しさん mailto:sage [2009/02/08(日) 09:55:54 ]
>>427 は、↓にすればコンパイルが通るぞ

let apply1 = function (F f) -> f 1;;

432 名前:デフォルトの名無しさん mailto:sage [2009/02/08(日) 11:15:40 ]
あっと、別にfunction使う必要はなかった

let apply1 (F f) = f 1;;

433 名前:デフォルトの名無しさん mailto:sage [2009/02/08(日) 13:03:49 ]
>>430,431
ありがとう。とても参考になりました。
let recは言語組み込みのYコンビネータみたいなもんらしいですね
無事できあがったYコンビネータ
type X = Psi_inv of (X -> (int -> int));;
let psi (Psi_inv f) = f;;
let Y g =
let h y = g(fun x -> (((psi y) y) x)) in
h(Psi_inv(h));;
(Y (fun f x -> if x=0 then 1 else x * f(x - 1))) 10;;
しかし、単純にF#に翻訳しただけなので
理解したとは言い難い・・

434 名前:デフォルトの名無しさん mailto:sage [2009/02/08(日) 18:21:09 ]
この流れなら書ける

type fix<'a, 'b> =
    Fix of (fix<'a, 'b> -> ('a -> 'b))
let y f =
    (fun (Fix g as h) x -> f (g h) x) (Fix (fun (Fix g as h) x -> f (g h) x))

y (fun f x -> if x = 1 then 1 else x * f (x-1)) 5
// val it : int = 120

[1..10] |> List.map (y (fun f x -> if x <= 2 then 1 else f (x-1) + f (x-2)))
// val it : int list = [1; 1; 2; 3; 5; 8; 13; 21; 34; 55]

435 名前:デフォルトの名無しさん mailto:sage [2009/02/08(日) 20:43:02 ]
同じ結論にたどり着いた
type Rec<'a,'b> = R of (Rec<'a,'b> -> ('a -> 'b));;
//version1
let y f =
let ymaker (R proc) = f(fun arg -> (proc (R proc)) arg) in
ymaker (R ymaker);;
//version1 extract
let y f =
(fun (R proc) -> f(fun arg -> (proc (R proc)) arg))
(R
(fun (R proc) -> f(fun arg -> (proc (R proc)) arg))
);;
//version 2
let R_inv (R f) = f;;
let y f =
let ymaker proc = f(fun arg -> (((R_inv proc) proc) arg)) in
ymaker (R ymaker);;
//version 2 extract
let y f =
(fun proc -> f(fun arg -> (((R_inv proc) proc) arg)))
(R
(fun proc -> f(fun arg -> (((R_inv proc) proc) arg)))
);;




436 名前:デフォルトの名無しさん mailto:sage [2009/02/10(火) 07:30:35 ]
Programming F#: Rough Cuts Version

By Chris Smith
Rough Cuts Release: February 2009
Print Book Release: October 2009
Pages: 504

俺、この本が出たらF#はじめるんだ・・・

437 名前:デフォルトの名無しさん mailto:sage [2009/02/11(水) 02:31:18 ]
のーみそが関数型に染まってくると
「左辺値」「右辺値」という言葉に
妙な違和感を覚えだす

そもそもそんな観念がないというか
あえて言うなら左辺に値などない

てなことを妄想してみたけどどうよ?

438 名前:デフォルトの名無しさん [2009/02/11(水) 04:31:13 ]
>>437
概念じゃねーの?

439 名前:デフォルトの名無しさん mailto:sage [2009/02/11(水) 08:56:56 ]
>>434-435
lazyに考えれば、もっとシンプルに書けるんじゃね(´・ω・`)?

let rec fix (f : Lazy<_>) = f.Force() (lazy fix f)

let fact = fix <| lazy fun f x -> if x = 0 then 1 else x * f.Force() (x - 1)

do fact 5 |> printfn "%d"

440 名前:デフォルトの名無しさん mailto:sage [2009/02/11(水) 09:01:08 ]
>>437
「let x = 1」
これは等式とは思わない方が自然じゃないだろうか。
もともとは数学の論文とかでよく出てくる
「Let x := 1.(xを1と置く。)」とかいう表記を構文にしただけなんじゃないかと想像する。
等式じゃないなら、左辺、右辺とかいう観念はない。

441 名前:デフォルトの名無しさん mailto:sage [2009/02/11(水) 09:18:39 ]
おまえら頭いい サイコーだ

442 名前:デフォルトの名無しさん mailto:sage [2009/02/11(水) 12:21:03 ]
>>439
>>429 をよく見ろ
> 最終的にやりたいことは、let recを用いずにYコンビネータを書きたい

443 名前:デフォルトの名無しさん mailto:sage [2009/02/11(水) 12:55:37 ]
ついでに、let rec 使用可なら lazy を使う必要すらない

let rec fix f x = f (fix f) x
let fact = fix <| fun f x -> if x = 0 then 1 else x * f (x - 1)

444 名前:デフォルトの名無しさん mailto:sage [2009/02/11(水) 13:39:14 ]
>>443
> let rec fix f x = f (fix f) x

あー、そっか。x つければ落ちないんだ。(´・ω・`)

let rec fix f = f (fix f)

と書いて、StackOverflowになってたのでlazyにしてた。

445 名前:デフォルトの名無しさん mailto:sage [2009/02/11(水) 13:47:41 ]
x はラムダ的に冗長に見えるけど、型推論の重要な手がかりになってるということか。

> let rec fix f = f (fix f);;

val fix : ('a -> 'a) -> 'a

> let rec fix f x = f (fix f) x;;

val fix : (('a -> 'b) -> 'a -> 'b) -> 'a -> 'b



446 名前:デフォルトの名無しさん mailto:sage [2009/02/11(水) 14:01:31 ]
そのあたりのことってProgramming in OCamlに書いてある
正格評価がどうのこうので。
試してないが、確かこれでもいけたはず
let rec y f = f (fun x -> y f x);;
fun arg -> (proc (R proc)) argの箇所を
(proc (R proc))としないのも同じ理由だと思う

とりあえずfunで包めばOK,みたいな

447 名前:デフォルトの名無しさん mailto:sage [2009/02/11(水) 14:31:19 ]
結局、再帰型を使うようにしたら、結論はほとんど同じだった。(´・ω・`)

type Fix<'a, 'b> = Fix of (Fix<'a, 'b> -> 'a -> 'b)

let run_fix (Fix f) = f

let ycomb f =
 let g proc = f (fun arg -> run_fix proc proc arg) in
 g (Fix g)

let fact = ycomb <| fun f n -> if n = 0 then 1 else n * f (n - 1)

448 名前:デフォルトの名無しさん mailto:sage [2009/02/11(水) 14:42:02 ]
>>438
正直、「観念」と「概念」の違いがわからんで調べてきた
どちらも「モノコトに対する意識・考え」だが…

* 観念
英語でいう idea の意味に近い
オレオレ解釈的(主観的)
故に観念は多様である

* 概念
英語でいう concept の意味に近い
ふつうはみんなそう解釈するよねー的(客観的)
故に概念は一様である

という違いがあるようだ。

左辺値、右辺値という考え方は、一般に共通の理解を得ている
もの(通念)であり、それらは「概念」と呼ぶのが相応しい
ということかな?

449 名前:デフォルトの名無しさん mailto:sage [2009/02/11(水) 14:45:18 ]
>>448
まあニュアンスが伝わればいいんじゃね?

450 名前:デフォルトの名無しさん mailto:sage [2009/02/12(木) 07:21:21 ]
>>445
冗長なんじゃなくて、正格評価の世界では意味が全く別のものになる。

let rec fix = fun f -> f (fix f)

let rec fix = fun f -> fun x -> f (fix f) x

後者では x が遅延の役割をしてくれる。

Haskellのような遅延評価の世界では、確かに冗長なだけ。

451 名前:デフォルトの名無しさん mailto:sage [2009/02/12(木) 07:31:11 ]
f そのものを遅延化してしまう(>>439)のと、
引数 x を追加して遅延の役割をしてもらう(>>443)のと、

どちらがコードの見た目的にやさしいかは明らか。w

452 名前:デフォルトの名無しさん mailto:sage [2009/02/13(金) 07:47:47 ]
f (fix f) と fun x -> f (fix f) x って同義じゃないの?

んー、マジで分からん

453 名前:デフォルトの名無しさん mailto:sage [2009/02/13(金) 19:50:03 ]
let rec fix f = f (fix f) だと、f が渡された途端、

f (fix f)

f (f (fix f))

f (f (f (fix f)))

f (f (f (f (fix f))))

f (f (f (f (f (fix f)))))

あぼーん

関数を返そうとはするが、fix を展開しようとして無限ループ。

let rec fix f = fun x -> f (fix f) x だと、f が渡されても、

fun x -> f (fix f) x

x が渡されるまで fix は展開されない。

454 名前:デフォルトの名無しさん mailto:sage [2009/02/13(金) 19:54:11 ]
ちょっと言葉足らずなので修正。

× 関数を返そうとはするが、fix を展開しようとして無限ループ。
○ 関数を返そうとはするが、先に fix を展開してしまい無限ループ。

× x が渡されるまで fix は展開されない。
○ 先に関数を返し、x が渡されるまで fix は展開されない。

455 名前:デフォルトの名無しさん mailto:sage [2009/02/14(土) 17:13:10 ]
関数は first-class object ではあっても
関数 = 値 ではない、と

――ここで正格評価において

let rec fix f = f (fix f) なる定義で fix g を評価しようとしたら?
必死こいて値を算出しようとしてしまうんだな
で、その結果、>>453 が示すように無限ループに陥る

let rec fix f x = f (fix f) x なる定義で fix g  を評価しようとしたら?
これは部分適用だから関数オブジェクトの生成を行うのだな
で、後々、(fix g) y とされたときに値の算出が始まる



456 名前:デフォルトの名無しさん mailto:sage [2009/02/15(日) 23:01:31 ]
高尚な議論の最中で流れぶった切ってゴメン

入れ子になった型宣言(ネストされた type)って無理?

type a () =
  type b = {x : int; y : int;}
  ...

とかすると、2つ目の type で
Unexpected keyword 'type' in type definition
と怒られる

457 名前:デフォルトの名無しさん mailto:sage [2009/02/17(火) 20:14:16 ]
>>456
できなさげ

確かに C# ではインナー クラスできるけど
Java と違ってそんなに多用されるもんでもないような

てか例示のコードならタプルでいいんじゃ?

458 名前:デフォルトの名無しさん mailto:sage [2009/02/17(火) 22:01:21 ]
ありがと、やっぱ出来なさそうですね。

まぁ、確かにタプルでも機能するんですが、
各要素へのアクセスが面倒なんで
レコードの方が扱いやすいなぁと。

459 名前:デフォルトの名無しさん mailto:sage [2009/02/18(水) 01:02:15 ]
.NET 言語なんで C# 基準で考えてしまいがちだが
F# は OCaml ベースなんだぜ?
internal すらぬるい、どうしても外部から隠蔽したいというなら
シグネチャ(.fsi)ファイルを書けばいいじゃないか

と、眠たいので調べもせずにいってみるテスト

460 名前:デフォルトの名無しさん mailto:sage [2009/02/18(水) 12:53:16 ]
>>259
公開するものだけをシグネチャ ファイルにしたら上手くいった。
なるほど、fsi はこうやって使うのか。
改めて読み直してみたら本には書かれていたけど、
いままで自分には無関係だと思って無視してた。
もうちょっと調べてみる。

じつは OCaml は見たことも触ったこともないんだけど、
やっぱ一通り触れてみた方がいいのかな・・・

461 名前:デフォルトの名無しさん mailto:sage [2009/02/18(水) 20:18:22 ]
>>259
言い忘れてた
ありがと

462 名前:デフォルトの名無しさん mailto:age [2009/03/04(水) 22:31:36 ]
seq<int> 型に拡張メソッドを加えたいです。

パラメータを int 型に制約しなければ例えば次のように出来ました。
type System.Collections.Generic.IEnumerable with
  member this.H = Seq.hd this

これを seq<int> 型の時のみ拡張することは出来ないのでしょうか。

463 名前:デフォルトの名無しさん mailto:sage [2009/03/07(土) 03:49:18 ]
これってVisual Studioから使えるの?

464 名前:デフォルトの名無しさん mailto:sage [2009/03/07(土) 04:09:35 ]
つかえるよ。
男は度胸。ものは試し。
まずはインストールしてミソ。

465 名前:デフォルトの名無しさん [2009/03/07(土) 09:32:33 ]
2008のProでしか駄目でした的な感じなのだが・・・orz
2008 Pro安く売ってないのかね



466 名前:デフォルトの名無しさん mailto:sage [2009/03/07(土) 13:05:24 ]
エディション比較ちゃんと見れと
www.microsoft.com/japan/msdn/vstudio/products/vs08/compare.aspx

相変わらず Visual Studio 2008 Shell は知られてないなと
msdn.microsoft.com/ja-jp/vsx2008/products/bb933751.aspx

アドインなんだから devenv.exe のあるなしで判断できるだろうと

467 名前:デフォルトの名無しさん mailto:sage [2009/03/07(土) 17:19:53 ]
使ってる人もっとなんか書いてくれ
Scala がどうとか言ってる同僚を黙らせたい


…俺? 日本語の本が出てからやるわw

468 名前:デフォルトの名無しさん mailto:sage [2009/03/07(土) 23:49:03 ]
F# のことを勉強しようかと思ったが、至るところ null があるって聞いた時点で、萎えた。

469 名前:デフォルトの名無しさん mailto:sage [2009/03/07(土) 23:56:45 ]
何を言ってるんだ?おまえは?

470 名前:デフォルトの名無しさん mailto:sage [2009/03/08(日) 00:07:37 ]
>>467
どうとか言ってる内容にもよるわけだが、黙らせる方法ってのは。
関数型サイコーとでも言っているのかい?その同僚は。

471 名前:デフォルトの名無しさん mailto:sage [2009/03/08(日) 02:04:51 ]
nullがあるって変な表現だよね。

472 名前:デフォルトの名無しさん mailto:sage [2009/03/08(日) 15:24:28 ]
>>466
kwsk

2008 StdあればF#の拡張機能は組み込めるってこと?
あと、VS2008 の Shell 版なら本体買う必要なすってことなのかな?

473 名前:472 mailto:sage [2009/03/08(日) 15:31:46 ]
ごめん、検索したら一杯情報出てきた。
大体あってた。

いげ太のブログ: Microsoft Visual Studio 2008 Shell (integrated mode) で F# 無償開発環境
igeta.cocolog-nifty.com/blog/2008/04/vsshell.html

> Microsoft Visual Studio 2008 Shell (integrated mode) を導入すれば、
> 無償の F# 開発環境が手に入る。噛み砕いて言えば、C# も VB.NET も C++/CLI も、
> 何の言語もバンドルされていない Visual Studio 2008 が、タダで手に入るってことだ。

> そして、VSShell がインストールされた状態で、F# をインストールすればよい。
> そうすれば VSShell に F# が組み込まれるのだ。

Visual Studio で F#の開発を行う - ピコピコの日記
d.hatena.ne.jp/net-k/20080911/1221099444

> F#はVisual Studio 2008 もしくは、Visual Studio 2008 Shellから利用することができる。
> Visual Studio 2008 を持っていないので、無償で公開されているVisual Studio 2008 Shellをダウンロードした。
> ちなみに、Visual Studio 2008 Shell とは、C++やC#などの開発環境が何も入っていない状態のVisual Studio 2008で、
> Visual Studio向けの開発環境をSDKを使って組み込むことができる。


Visual Studio Shellダウンロードしてくるわ。
ありがとう。

474 名前:デフォルトの名無しさん mailto:sage [2009/03/09(月) 22:36:42 ]
>>468 はこれか。
d.hatena.ne.jp/camlspotter/

いろいろ挑発的なことが書いてあるな

475 名前:デフォルトの名無しさん [2009/03/22(日) 17:40:50 ]
下がりすぎだろ



476 名前:デフォルトの名無しさん [2009/03/24(火) 16:39:37 ]
FParsecの話なんかやってくれないかなあ

477 名前:デフォルトの名無しさん mailto:sage [2009/03/24(火) 20:11:44 ]
こやつめw






[ 新着レスの取得/表示 (agate) ] / [ 携帯版 ]

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

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