2009-05-10 9 views
13

Mam ciąg FileInfo, ale zależy mi tylko na ich nazwach ciągów, więc chcę sekwencji ciąg. Początkowo próbowałem coś takiego:Dlaczego nie można tego zrozumieć za pomocą interferencji typu F #?

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

Ale z jakiegoś powodu, F # 's typ wnioskowanie nie jest wystarczająco dobry, aby umożliwić tym i mnie wyraźnie podać typ na «fi»:

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

Dlaczego ta adnotacja jest wymagana? Jeśli wiadomo, że fis : seq<FileInfo> i Seq.map : ('a -> 'b) -> seq<'a> -> seq<'b>, to czy nie należy wnioskować, że typ wyrażenia lambda to FileInfo -> 'b, a następnie, od fi.Name : string, dalej wnioskować, że jego typ to FileInfo -> string?

Odpowiedz

24

Inferencja typów działa od lewej do prawej. W tym miejscu użyteczny jest operator rurociągu; jeśli znasz już typ "fis", a następnie napisz go jako pomocniczy, a wnioskowanie działa dla ciebie.

(Generalnie wyrażenia postaci

o.Property 
o.Method args 

wymagają typu „O”, aby być znana priori, dla większości innych określeń, gdy typ nie muru systemu Wnioskowanie może 'float a' constraint ', który może być później rozwiązany, ale w tych przypadkach nie ma ograniczeń formy "wszystkie typy z właściwością o nazwie P" lub "wszystkie typy z metodą o nazwie M" (jak pisanie kaczką), które mogą być odroczone i rozwiązane później, więc potrzebujesz tych informacji teraz, lub wnioskowanie nie powiedzie się natychmiast.)

Zobacz także overview of type inference in F#.

+4

Mam nadzieję, że wnioskowanie typu będzie bardziej wytrzymałe. Udało mi się już trafić w kilka przypadków, w których musiałem zmienić kolejność metod w klasie lub uzyskać zbyt ogólne błędy typu. – gradbot

+1

Co jest warte uwagi, ten wpis na blogu i niektóre z jego komentarzy zawierają użyteczne wyjaśnienie niektórych mocnych i słabych stron F # w sprawdzaniu typu: http://neilmitchell.blogspot.com/2008/12/f-from-haskell- perspective.html – Juliet

Powiązane problemy