Fsharp - types compilation error

150 views Asked by At

I am new to F#, and I'd love to get some help :)

I have ? compilation error on this code, and I can't figure it out:

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))

The compiler shouts this error:

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

about the if ((Path.GetExtension(file)).Equals(".jack")) then JackFiles.Add(file)) part...

Why is it wrong and how do I fix it?

2

There are 2 answers

0
Lee On BEST ANSWER

The function argument to Seq.iteri requires two arguments and should have type (int -> 'T -> unit). Its file parameter is inferred to have type int and therefore your if statement should have type string -> unit but actually has type unit, hence the error.

It looks like you don't require the int argument so you can use Seq.iter instead.

However it looks like what you're trying to do could be done using something similar to:

let jackFiles = Directory.GetFiles(dir, "*.jack")
2
pad On

In addition to @Lee's answer, I have several remarks:

  • One way to avoid your error is to use for loop instead of Seq.iter(i). I find for loop is more readable without having to deal with closure.
  • System.Collections.Generic.List<T> exists in F# under the name ResizeArray. You even have ResizeArray module in F# PowerPack with all necessary high-order functions.
  • One should you = instead of obj.Equals.

Applying above comments, your solution looks like:

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