2009-07-15 10 views
1

これは私のコードです:F#がこの型を推論するのはなぜですか?

type Cell<'t>(initial : 't) = 
    let mutable v = initial 
    let callbacks = new List<'t -> unit>() 
    member x.register c = callbacks.Add(c) 
    member x.get() = v 
    member x.set v' = 
     if v' <> v 
     then v <- v' 
      for callback in callbacks do callback v' 
    member x.map f = 
     let c = new Cell<_>(f v) 
     x.register(fun v' -> c.set (f v')) ; c 

私の問題はmapメンバーです。

map : ('t -> 'a) -> Cell<'a> 

そして実際に、私はそのように型を宣言する場合、Visual Studioがいることを私に語った:F#が、私はそれが(ちょうど配列のマップのように)このより一般的なタイプを推測すべきだと思うタイプ

map : ('t -> 't) -> Cell<'t> 

を推論します型 'aは(f v')の式c.set (f v')のために制限されていません。クラス定義のため、新しいセルにCell < 't>という型が強制されてしまう問題がありますか?すなわち

map : ('a -> 'b) -> Cell<'a> -> Cell<'b> 
私が使用したい

let map f (c : Cell<_>) = 
    let c' = new Cell<_>(f (c.get())) 
    c.register(fun v' -> c'.set (f v')) ; c' 

は、私は別の関数としてマップを定義するならば、F#は、私が欲しい種類を推測んので、それが問題だかなり確信していますメンバーですが、これほど一般的ではないタイプは、私のCell型を役に立たなくします...どうすればこの問題を解決できますか?

ありがとうございます! Jules

答えて

2

私は今すぐベータ1のボックスを持っていません(私たちの内部ビットでは正しいタイプを推測しているようですので、これはBeta2で修正されることを意味します)。

私はあなたが完全な型シグネチャを指定することができ期待:

member x.map<'a> (f:'t -> 'a) : Cell<'a> = 

をし、それが動作します。

UPDATE

私はベータ1に試みたが、実際には '修正' は署名ができます。このタイプを追加し、なぜ私は不明だ

member x.set (v':'t) : unit = 

です。

+0

ありがとうございます!そのシグネチャは奇妙です: ':unit'を削除した場合や' v 'を削除した場合:' t'その後、F#は再び制限付きの型を推測します!そして、あなたが署名F#を指定しなければ、同じ型を推測します...もう一度ありがとう! – Jules

関連する問題