2009-07-15 119 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成員。 F#推斷類型

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

我想應該推斷更一般的類型(就像序列的地圖):

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

而事實上,如果我聲明這樣的類型時,Visual Studio告訴我,由於表達式(f v')c.set (f v')中,類型'a已經被限制爲't'。是否因爲我們處於類定義中而迫使新單元格輸入Cell <'t>的問題?

我敢肯定,這就是問題所在,因爲如果我定義地圖作爲一個單獨的函數,那麼F#並推斷出我想要的類型:

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

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

我想用一個成員,但這種較不常見的類型使得我的Cell類型無用......我如何解決這個問題?

謝謝! Jules

回答

2

我現在沒有一個方便Beta1的盒子(在我們的內部位現在似乎推斷出正確的類型,所以希望這意味着這將在Beta2中得到解決)。

我希望你可以指定一個完整的類型簽名:

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

,它會工作。

UPDATE

我試了Beta1的,而事實上 '修復' 是

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

我不清楚爲什麼增加這個類型簽名幫助。

+0

謝謝!這個簽名很奇怪:如果你刪除`:unit`或者如果你刪除`v':'t`,那麼F#再次推斷出限制類型!如果您不指定簽名F#推斷相同的類型...再次感謝! – Jules 2009-07-16 12:49:15

相關問題