Почему 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>

Я думаю, что это должно сделать этот более общий тип (как и карта Seq):

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

И на самом деле, если я объявляю такой тип, Visual Studio говорит мне, что тип 'a был ограничен' t из-за выражения (f v') в c.set (f v'). Является ли проблема, что новая ячейка вынуждена иметь тип 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>

Я хотел бы использовать элемент, но этот менее общий тип делает мой тип ячейки бесполезным... Как решить эту проблему?

Спасибо! Jules

Ответы

Ответ 1

У меня нет коробки с Beta1 под рукой прямо сейчас (в наших внутренних битах это теперь, кажется, выводит правильный тип, поэтому, надеюсь, это означает, что это будет исправлено в Beta2).

Я ожидаю, что вы можете указать подпись полного типа:

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

и он будет работать.

UPDATE

Я попробовал на Beta1, и на самом деле "fix" есть

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

Непонятно, почему добавление этой сигнатуры типа помогает.