Почему логический тип F# не может это обработать?

У меня есть последовательность 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 ответ

Решение

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

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

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

(В общем, выражения вида

o.Property
o.Method args

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

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

Другие вопросы по тегам