错误 FS0001:类型 'string -> seq<unit>' 与类型 'seq<'a>' 不兼容
Error FS0001: The type 'string -> seq<unit>' is not compatible with the type 'seq<'a>'
我很难理解 F# 中的错误消息,因为这是我第一次使用类型化的函数式语言。这是我的代码示例:
let getAllFiles (directory : string) =
Directory.GetFiles(directory)
let getFileInfo =
getAllFiles
|> Seq.map (fun eachFile -> (eachFile, new FileInfo(eachFile)))
我收到以下错误消息:"Error FS0001: The type 'string -> seq' is not compatible with the type 'seq<'a>'"
我可以做哪些改变?提前谢谢你。
由于您正在组合函数,而不是将值从一个函数传递到另一个函数,因此您必须使用组合运算符 (>>
) 而不是管道 (|>
):
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)))
评论更新:
If I specifically want to get the file length, how should I write it instead?
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
.
的名字
更新第二条评论:
I would like to group the tuples according to the length of each file using Seq.groupBy. How may I go about doing so?
函数 removeSingletonGroups
删除所有只包含一个值的组。
函数getFilesGroupedByLength
首先使用Seq.groupBy
创建以文件长度为键的组,然后使用Seq.map
从值中删除文件长度,因此每个的值group 只是一个文件名列表。最后它使用 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
您需要将目录提供给 getAllFiles
例如
let getFileInfo =
getAllFiles "directory to search"
|> Seq.map (fun eachFile -> (eachFile, new FileInfo(eachFile)))
通常,当您遇到这样的错误时,函数类型 a -> ... -> b
与类型 b
不兼容,那么您没有为正在使用的函数提供足够的参数。
我很难理解 F# 中的错误消息,因为这是我第一次使用类型化的函数式语言。这是我的代码示例:
let getAllFiles (directory : string) =
Directory.GetFiles(directory)
let getFileInfo =
getAllFiles
|> Seq.map (fun eachFile -> (eachFile, new FileInfo(eachFile)))
我收到以下错误消息:"Error FS0001: The type 'string -> seq' is not compatible with the type 'seq<'a>'"
我可以做哪些改变?提前谢谢你。
由于您正在组合函数,而不是将值从一个函数传递到另一个函数,因此您必须使用组合运算符 (>>
) 而不是管道 (|>
):
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)))
评论更新:
If I specifically want to get the file length, how should I write it instead?
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
.
更新第二条评论:
I would like to group the tuples according to the length of each file using Seq.groupBy. How may I go about doing so?
函数 removeSingletonGroups
删除所有只包含一个值的组。
函数getFilesGroupedByLength
首先使用Seq.groupBy
创建以文件长度为键的组,然后使用Seq.map
从值中删除文件长度,因此每个的值group 只是一个文件名列表。最后它使用 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
您需要将目录提供给 getAllFiles
例如
let getFileInfo =
getAllFiles "directory to search"
|> Seq.map (fun eachFile -> (eachFile, new FileInfo(eachFile)))
通常,当您遇到这样的错误时,函数类型 a -> ... -> b
与类型 b
不兼容,那么您没有为正在使用的函数提供足够的参数。