这是我的代码:
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>
我认为它应该推断出这种更通用的类型(就像Seq的地图一样):
map : ('t -> 'a) -> Cell<'a>
事实上,如果我声明类似的类型,Visual Studio会告诉我,由于(f v')
中的表达式c.set (f v')
,类型'a'已被约束为't}。问题是新Cell被迫具有类型Cell&lt; t&gt;因为我们在课堂定义中?
我很确定这是问题所在,因为如果我将map定义为一个单独的函数,那么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类型无用......我该如何解决这个问题?
谢谢! 朱
答案 0 :(得分:2)
我现在没有方便使用Beta1的方框(在我们的内部位中,现在似乎推断出正确的类型,所以希望这意味着这将在Beta2中修复)。
我希望您可以指定完整类型签名:
member x.map<'a> (f:'t -> 'a) : Cell<'a> =
它会起作用。
<强>更新强>
我试过Beta1,实际上'修复'是
member x.set (v':'t) : unit =
我不清楚为什么添加此类签名会有所帮助。