I'm just starting with F# so I thought I would try some simple tasks.
This lists the full paths to the xml files in a directory:
System.IO.Directory.GetFiles("c:\\tmp", "*.xml")
|> Array.iter (printfn "%s")
But I want only the file names so I tried:
System.IO.Directory.GetFiles("c:\\tmp", "*.xml")
|> Array.iter (System.IO.Path.GetFileName)
|> (printfn "%s")
This won't compile. It gives the error:
This expression was expected to have type
unit
but here has type
string
I searched for examples but couldn't find anything. I'm obviously missing something simple and fundamental, but what?
Answer: 1° Celsius is equivalent to 33.8° Fahrenheit.
37.4 °C = 99.4 °F 37.6 °C = 99.6 °F. 37.7 °C = 99.8 °F. 37.8 °C = 100.0 °F. 37.9 °C = 100.2 °F.
Definition: The Fahrenheit (symbol: °F) is a unit of temperature that was widely used prior to metrication. It is currently defined by two fixed points: the temperature at which water freezes, 32°F, and the boiling point of water, 212°F, both at sea level and standard atmospheric pressure.
Since you are new, one thing to make it easer to fix errors is to think of statements like mathematical statements that can be built up of simpler functions but that can also be factored apart.
So by factoring apart your problem you can get a finer grained error that becomes easier to solve.
System.IO.Directory.GetFiles("c:\\tmp", "*.xml")
|> Array.iter (System.IO.Path.GetFileName)
|> (printfn "%s")
is factored apart into
let directoryArray = System.IO.Directory.GetFiles("c:\\tmp", "*.xml")
let nameArray = Array.iter (System.IO.Path.GetFileName) directoryArray
(printfn "%s") nameArray
now the errors should be much easier to understand
If we look at the signature of Array.iter
which is iter : ('T -> unit) -> 'T [] -> unit
we see that it needs a function ('T -> unit)
that takes a type and returns a unit
which means return nothing, in this case printing would work, however you do not want to return nothing you want to convert the array of directories into an array of filenames. So Array.iter
will not work and you need a Array function that applies a function to each item in the array and returns a new Array
, Array.map
does this map : ('T -> 'U) -> 'T [] -> 'U []
To better understand the Array functions and see how they work one can add a lambda function
.
Likewise with (printfn "%s")
; one can add a lambda function to pass in a value.
let directoryArray = System.IO.Directory.GetFiles("c:\\tmp", "*.xml")
let nameArray = Array.map (fun x -> (Path.GetFileName(x))) directoryArray
Array.iter (fun x -> printfn "%s" x) nameArray
Now we can simplify the statements using |>
System.IO.Directory.GetFiles("c:\\tmp", "*.xml")
|> Array.map (fun x -> (Path.GetFileName(x)))
|> Array.iter (fun x -> printfn "%s" x)
and simplify again by removing the lambdas
open System.IO
Directory.GetFiles("c:\\tmp", "*.xml")
|> Array.map Path.GetFileName
|> Array.iter (printfn "%s")
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With