我很难理解F#中的错误消息,因为这是我第一次使用类型化的函数语言。以下是我的代码示例:
let getAllFiles (directory : string) =
Directory.GetFiles(directory)
let getFileInfo =
getAllFiles
|> Seq.map (fun eachFile -> (eachFile, new FileInfo(eachFile)))
我收到以下错误消息:"错误FS0001:类型'字符串 - > SEQ'与' seq<'''""
类型不兼容我可以做出哪些改变?提前谢谢。
答案 0 :(得分:3)
由于您正在编写函数,而不是将值从一个函数传递到另一个函数,因此必须使用复合运算符(>>
)而不是管道(|>
):
open System.IO
let getAllFiles (directory : string) =
Directory.GetFiles(directory)
let getFileInfo =
getAllFiles
>> Seq.map (fun eachFile -> (eachFile, new FileInfo(eachFile)))
或者,您可以使参数显式,然后您可以使用管道:
open System.IO
let getAllFiles (directory : string) =
Directory.GetFiles(directory)
let getFileInfo directory =
directory
|> getAllFiles
|> Seq.map (fun eachFile -> (eachFile, new FileInfo(eachFile)))
评论更新:
如果我特意想要获取文件长度,我该怎么写呢?
open System.IO
let getAllFiles directory =
Directory.GetFiles directory
let getFileInfos =
getAllFiles
>> Seq.map (fun fileName -> (fileName, FileInfo fileName))
let getFileLengths =
getFileInfos
>> Seq.map (fun (fileName, fileInfo) -> fileName, fileInfo.Length)
如果您要获取目录中所有文件的所有文件长度,可以使用上面代码中的getFileLengths
函数。请注意,我修改了getFileInfo
的名称。
第二条评论的更新:
我想使用Seq.groupBy根据每个文件的长度对元组进行分组。我怎么可能这样做?
函数removeSingletonGroups
删除仅包含一个值的所有组。
函数getFilesGroupedByLength
首先使用Seq.groupBy
创建文件长度为键的组,然后使用Seq.map
从值中删除文件长度,因此每个组的值为只有文件名列表。最后,它使用removeSingletonGroups
清除所有只包含一个文件的组。
let removeSingletonGroups groupedSeq =
groupedSeq
|> Seq.filter (snd >> List.length >> (<>) 1)
let getFilesGroupedByLength =
getFileLengths
>> Seq.groupBy snd
>> Seq.map (fun (fileLength, files) -> fileLength, files |> Seq.map fst |> List.ofSeq)
>> removeSingletonGroups
最终(?)更新:
我刚看到有关重复文件检查程序的问题。我认为这种方法正是您所寻求的:
open System.IO
let getFilesOfDirectory directoryPath =
Directory.EnumerateFiles directoryPath
let getFileLength filePath =
(FileInfo filePath).Length
let groupFilesByLength files =
files
|> Seq.groupBy getFileLength
let removeSingletonGroups groupedSeq =
groupedSeq
|> Seq.filter (fun (_, group) -> Seq.length group > 1)
let getDuplicateFileCandidates directoryPath =
directoryPath
|> getFilesOfDirectory
|> groupFilesByLength
|> removeSingletonGroups
答案 1 :(得分:0)
您需要将目录提供给getAllFiles
,例如
let getFileInfo =
getAllFiles "directory to search"
|> Seq.map (fun eachFile -> (eachFile, new FileInfo(eachFile)))
通常,当您收到类似的错误时,函数类型a -> ... -> b
与类型b
不兼容,那么您没有为您正在使用的函数提供足够的参数。