为什么F#推断出这种类型的?(Why does F# infer this type?)

2019-09-28 02:23发布

这是我的代码:

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告诉我,典型的有一个已经被限制为‘T,因为表达式的(f v')c.set (f v') 是新的细胞被迫有型格的问题<'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>

我想用一个成员,但是这不太普通型使我的细胞类型没用......我该如何解决这个问题?

谢谢! 儒勒

Answer 1:

我没有与目前的Beta1得心应手箱(在我们的内部位这个现在看来推断正确的类型,所以希望这意味着这将是固定在Beta2中)。

我希望你可以指定一个完整的类型签名:

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

它会工作。

UPDATE

我试了Beta1的,而事实上“修复”是

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

我不清楚为什么增加这个类型签名帮助。



文章来源: Why does F# infer this type?