在F#中:如何获取目录中的文件名列表;预期单位有字符串

时间:2016-02-18 12:18:50

标签: f# getfiles

我刚开始使用F#,所以我想我会尝试一些简单的任务。

这列出了目录中xml文件的完整路径:

System.IO.Directory.GetFiles("c:\\tmp", "*.xml")
|> Array.iter (printfn "%s")

但我只想要文件名,所以我试过了:

System.IO.Directory.GetFiles("c:\\tmp", "*.xml")
|> Array.iter (System.IO.Path.GetFileName)
|> (printfn "%s")

这不会编译。它给出了错误:

预计此表达式具有类型     单元
但这里有类型     字符串

我搜索了一些例子但找不到任何东西。我显然缺少一些简单而基本的东西,但是什么呢?

1 个答案:

答案 0 :(得分:9)

因为你是新手,所以更容易修复错误的一件事是想到像数学陈述这样的陈述,这些陈述可以用更简单的函数构建,但也可以分开考虑。

因此,通过分解您的问题,您可以获得更容易解决的更细粒度的错误。

System.IO.Directory.GetFiles("c:\\tmp", "*.xml")
|> Array.iter (System.IO.Path.GetFileName)
|> (printfn "%s")

被分解为

let directoryArray = System.IO.Directory.GetFiles("c:\\tmp", "*.xml")
let nameArray = Array.iter (System.IO.Path.GetFileName) directoryArray
(printfn "%s") nameArray 

现在错误应该更容易理解

如果我们查看Array.iter iter : ('T -> unit) -> 'T [] -> unit的签名,我们会发现它需要一个函数('T -> unit),它接受​​一个类型并返回unit,这意味着什么都不返回,在这种情况下,打印可以工作,但是您不希望返回任何想要将目录数组转换为文件名数组的内容。所以Array.iter将不起作用,你需要一个Array函数,它将一个函数应用于数组中的每个项目并返回一个新的ArrayArray.map执行此操作map : ('T -> 'U) -> 'T [] -> 'U []以便更好地理解数组函数并查看它们如何工作,可以添加lambda function

(printfn "%s")同样;可以添加一个lambda函数来传递一个值。

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

现在我们可以使用|>

简化语句
System.IO.Directory.GetFiles("c:\\tmp", "*.xml")
|> Array.map (fun x -> (Path.GetFileName(x)))
|> Array.iter (fun x -> printfn "%s" x)

并删除lambdas

再次简化
open System.IO

Directory.GetFiles("c:\\tmp", "*.xml") 
|> Array.map Path.GetFileName 
|> Array.iter (printfn "%s") 
相关问题