Почему логический тип F # не может это обработать? - PullRequest
13 голосов
/ 10 мая 2009

У меня есть последовательность FileInfo, но я забочусь только об их именах строк, поэтому я хочу последовательность строк. Сначала я попробовал что-то вроде этого:

Seq.map (fun fi -> fi.Name) fis

Но по какой-то причине логический вывод типа F # недостаточно хорош, чтобы позволить это, и заставил меня явно указать тип для "fi":

Seq.map (fun (fi : FileInfo) -> fi.Name) fis

Зачем нужна эта аннотация? Если известно, что fis : seq<FileInfo> и Seq.map : ('a -> 'b) -> seq<'a> -> seq<'b>, то не следует ли из этого сделать вывод, что тип лямбда-выражения равен FileInfo -> 'b, а затем, из fi.Name : string, сделать вывод, что его тип равен FileInfo -> string?

1 Ответ

24 голосов
/ 10 мая 2009

Вывод типа работает слева направо. Это где оператор трубопровода полезен; если вы уже знаете тип 'fis', напишите его как

fis |> Seq.map (fun fi -> fi.Name)

и вывод работает для вас.

(В общем случае выражения вида

o.Property
o.Method args

требует, чтобы тип 'o' был известен a priori ; для большинства других выражений, когда тип не закреплен, система логического вывода может «переместить ограничение», которое может быть решено позже, но для этих случаев нет ограничений формы «все типы со свойством с именем P» «все типы с методом с именем M» (например, утки), которые можно отложить и решить позже. Таким образом, вам нужна эта информация сейчас, иначе вывод не удастся немедленно.)

См. Также обзор вывода типов в F # .

...