2012-05-30 99 views
0

我是F#的新手,我很想得到一些帮助:)Fsharp - 类型编译错误

我有吗?这个代码编译错误,我不能弄明白:

printfn "Please enter the path for the Jack file/s directory" 
let dir = System.Console.ReadLine() 
let jackFiles : List<String> = (new List<String>()) 
dir 
|> Directory.GetFiles 
|> Seq.iteri(fun file -> if ((Path.GetExtension(file)).Equals(".jack")) then JackFiles.Add(file)) 

编译器呼喊此错误:

This expression was expected to have type string->unit but here has type unit

有关if ((Path.GetExtension(file)).Equals(".jack")) then JackFiles.Add(file))部分...

为什么是错的我该如何解决它?

回答

2

Seq.iteri的函数参数需要两个参数,并且应该有(int -> 'T -> unit)类型。它的文件参数被推断为具有类型int,因此您的if语句应具有类型string -> unit,但实际上具有类型unit,因此是错误。

它看起来就像你不需要int参数,因此你可以使用Seq.iter代替。

然而,它看起来像你想要做什么可以使用类似的东西来完成:

let jackFiles = Directory.GetFiles(dir, "*.jack") 
+0

这是正确的....感谢ü非常感谢! – cookya

1

除了@李的回答,我有几点看法:

  • 的一种方式避免你的错误是使用for循环而不是Seq.iter(i)。我发现for循环更具可读性,无需处理闭包。
  • System.Collections.Generic.List<T>以名称ResizeArray的名义存在于F#中。您甚至在F#PowerPack中拥有ResizeArray module以及所有必需的高阶函数。
  • 你应该=而不是obj.Equals

应用上述意见,您的解决方案是这样的:

let jackFiles = ResizeArray() 
for file in Directory.GetFiles(dir) do 
    if Path.GetExtension(file) = ".jack" then jackFiles.Add(file) 
+0

谢谢!但为什么使用=而不是obj.Equals? – cookya

+0

@cookya:它们在这里意思相同,'='更短更实用。 – pad

+0

好的,谢谢:) – cookya