Почему логический тип 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#.