Почему вывод типа F# не может справиться с этим?

StackOverflow https://stackoverflow.com/questions/844733

  •  20-08-2019
  •  | 
  •  

Вопрос

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

Это было полезно?

Решение

Вывод типа работает слева направо.Вот тут-то и пригодится оператор конвейера;если вы уже знаете тип «фис», то напишите его как

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

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

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

o.Property
o.Method args

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top