F#查找最近5天内修改的子目录中的所有文件

F#查找最近5天内修改的子目录中的所有文件,f#,F#,我对F#还比较陌生,所以请温柔一点。我试图以函数式的方式编写代码,在目录(和子目录)中查找过去5天内修改的所有文件,然后处理这些文件(目前只是将名称写入控制台) 我的密码是: open System.IO let rec getAllFiles dir pattern = seq { yield! Directory.EnumerateFiles(dir, pattern) for d in Directory.EnumerateDirectories(dir) d

我对F#还比较陌生,所以请温柔一点。我试图以函数式的方式编写代码,在目录(和子目录)中查找过去5天内修改的所有文件,然后处理这些文件(目前只是将名称写入控制台)

我的密码是:

open System.IO

let rec getAllFiles dir pattern =
    seq { yield! Directory.EnumerateFiles(dir, pattern)
          for d in Directory.EnumerateDirectories(dir) do
              yield! getAllFiles d pattern }

let printMe x = printfn "%A" x

let hasChangedRecently fileName =
    let myFile = System.IO.FileInfo(fileName)
    let f myFile = function
    | myFile when myFile.LastWriteTime >= System.DateTime.Parse "10-04-2015" -> printMe MyFile.Name
    | _ -> ()

    f fileName

[<EntryPoint>]
let main argv =
    getAllFiles @"c:\temp" "*.xml"
    |> Seq.iter hasChangedRecently

    System.Console.ReadKey() |> ignore
    0 // return an integer exit code

我确信这些都是基本错误,但我真诚地希望得到一些指导。

我会将
最近更改的
函数更改为
string->bool
函数,并使用它过滤文件,然后使用单独的函数打印文件

let hasChangedRecently fileName =
    let myFile = System.IO.FileInfo(fileName)
    myFile.LastWriteTime >= System.DateTime.Parse "10-04-2015"

let printFile file =
    printfn "%s" file

getAllFiles @"c:\temp" "*.xml"
|> Seq.filter hasChangedRecently
|> Seq.iter printFile
此外,如果您愿意,可以使用.NET中内置的
SearchOption.AllDirectories
避免
getAllFiles
被递归:

Directory.EnumerateFiles(dir, pattern, SearchOption.AllDirectories)

我想你也可以像这样重写
hasChangedRecently
(并让它打印结果)

如果你想使用这个函数,你必须设法帮助编译器推断类型。在这种情况下,您可以编写:

let hasChangedRecently fileName =
    let analyze: (System.IO.FileInfo -> _) = 
        function 
        | x when x.LastAccessTime > System.DateTime.Parse "10-04-2015" -> printfn "%s" x.Name 
        | _ -> ()
    analyze System.IO.FileInfo(fileName)

正如Vandroy在他的评论中解释的那样,
函数
对未命名的参数进行模式匹配。在这里,我们刚刚定义了
analyze
的类型,它是一个函数,在参数中获取一个FileInfo,然后返回任何值。

为了得到它的值,
枚举文件
,它通过搜索所有子目录为您执行递归。是的,这也可以,谢谢。请你解释一下我做错了什么。什么时候应该使用function关键字,什么时候应该使用直接的“匹配”?好吧,我认为代码中有几个问题,因为您将myFile重用为“f”函数的参数。在f函数的定义中,编译器无法推断此myFile参数的类型。但是,即使用x替换myFile,并给出类型注释,它仍然不能与“function”一起工作。我必须调查一下为什么。。。同时,我必须承认,在这种情况下,我经常让编译器驱动我修改代码,直到他不再叫喊为止。@PeterB
function
声明一个函数,该函数接受一个未命名的参数并对其进行模式匹配。换句话说,它的意思类似于
fun arg0->match arg0 with
。在问题中,code
let f myFile=function
创建了一个具有两个参数的函数,其中第一个参数绑定到名称
myFile
,第二个参数进入模式匹配。然后,在模式匹配器中,
myFile
再次绑定,将函数参数隐藏起来,该参数从未使用过。@vandroy!经过一个美好的夜晚,我有了更新鲜的想法,并想给出同样的解释。我将编辑我的答案来说明它。如果需要,您可以像这样定义
printFile
函数,并得到相同的结果:
let printFile=printfn“%s”
let hasChangedRecently fileName =
    match  System.IO.FileInfo(fileName) with
    | myFile when myFile.LastWriteTime >= System.DateTime.Parse "10-04-2015" -> printfn "%s" myFile.Name
    | _ -> ()
let hasChangedRecently fileName =
    let analyze: (System.IO.FileInfo -> _) = 
        function 
        | x when x.LastAccessTime > System.DateTime.Parse "10-04-2015" -> printfn "%s" x.Name 
        | _ -> ()
    analyze System.IO.FileInfo(fileName)