我对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
在hasChangedRecently块中出错了。
错误是:
myFile.LastWriteTime
Lookup on object of indeterminate type based on information prior to this program point. A type annotation may be needed prior to this program point to constrain the type of the object. This may allow the lookup to be resolved.
MyFile.Name
The namespace or module 'MyFile' is not defined
|> Seq.iter hasChangedRecently
Type mismatch. Expecting a
string -> unit
but given a
string -> 'a -> unit
The type 'unit' does not match the type ''a -> unit'
我很确定这些是基本的错误,但会真诚地感谢一些指导。
答案 0 :(得分:5)
我会将hasRecentlyChanged
更改为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
和main
:
getAllFiles @"c:\temp" "*.xml"
|> Seq.filter hasChangedRecently
|> Seq.iter printFile
此外,如果您愿意,可以使用.NET内置的getAllFiles
来避免SearchOption.AllDirectories
递归:
Directory.EnumerateFiles(dir, pattern, SearchOption.AllDirectories)
答案 1 :(得分:1)
我认为您也可以像这样重写hasChangedRecently
(并让它打印结果)
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)
正如Vandroiy在他的评论中所说的那样,function
对未命名的论证进行了模式匹配。在这里,我们只是将analyze
的类型定义为在参数中获取FileInfo并返回任何内容的函数。