Почему F # выводит этот тип? - PullRequest
1 голос
/ 16 июля 2009

Это мой код:

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>

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

Спасибо! Jules

1 Ответ

2 голосов
/ 16 июля 2009

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

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

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

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

ОБНОВЛЕНИЕ

Я пробовал на Beta1, и на самом деле 'fix 'is

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

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

...