2012-10-25 28 views
0

我試圖從某些文件的名稱構建列表。不幸的是,我收到了一個我不知道如何糾正的類型錯誤。在F中構建列表時類型不匹配#

我的代碼: -

open System 

let buildStringList (list: string []) = 

     let initial = [] 
      for i = 0 to list.Length do 
       let foo = list.[i] 
       List.append initial foo.Substring(foo.IndexOf(".")) 

錯誤類型: -

error FS0001: This expression was expected to have type string -> 'a 
    but here has type string 

而這涉及到 「foo.Substring(foo.IndexOf(」 「)。)」 對象。在這裏獲得正確類型的最佳方式是什麼?

非常感謝。

回答

2

我覺得這是做你想要什麼功能更強大的方式:

open System 

let buildStringList (list: string []) = 
     list |> Array.toList |> List.map (fun x -> x.Substring(x.IndexOf("."))) 

的原因爲您的特定錯誤是List.append需要兩個列表,而不是一個列表和單個項目。

+0

權。是的,這是有道理的。多麼愚蠢的錯誤。 –

5

縮進你的功能是完全關閉的。無論如何,foo.Substring(foo.IndexOf("."))string,其不是List.append所要求的list類型。

你想要的是將一個元素添加到累加器列表中。你的函數速戰速決使用mutable值:

let buildStringList (arr: string []) = 
    let mutable result = [] 
    for i = 0 to arr.Length do 
     let foo = arr.[i] 
     result <- foo.Substring(foo.IndexOf("."))::result 
    List.rev result // Use List.rev if you would like to keep the original order 

但是,推薦的方法是使用高階功能。當使用List.map馬克的回答是一個很好的方法,可以用Array.fold更接近你的代碼:

let buildStringList (arr: string []) = 
    arr 
    |> Array.fold (fun acc foo -> foo.Substring(foo.IndexOf("."))::acc) [] 
    |> List.rev 

是完整的,列表理解也有利於在某些情況下:

let buildStringList (arr: string []) = 
    [ for foo in arr -> foo.Substring(foo.IndexOf(".")) ] 
+2

感謝您花時間將列表中的字符串[]參數重命名爲arr;正確的名字在代碼可讀性方面有很長的路要走,反之,像list |> Array.toList這樣的代碼(在另一個答案中)是沒有理由的。 – Mathias

+0

@Mathias:起初我也很困惑。重命名變量可以幫助我正確地寫出答案:)。 – pad

+0

好點@Mathias,感謝您的發現。 –