错误FS0001:类型&#39;字符串 - &gt; SEQ <单元>&#39;与&#39; seq&lt;&#39; a&gt;&#39; </unit>类型不兼容

时间:2015-03-06 11:21:28

标签: f#

我很难理解F#中的错误消息,因为这是我第一次使用类型化的函数语言。以下是我的代码示例:

let getAllFiles (directory : string) =
    Directory.GetFiles(directory)
let getFileInfo =
    getAllFiles 
    |> Seq.map (fun eachFile -> (eachFile, new FileInfo(eachFile)))

我收到以下错误消息:&#34;错误FS0001:类型&#39;字符串 - &gt; SEQ&#39;与&#39; seq&lt;&#39;&#39;&#39;&#34;&#34;

类型不兼容

我可以做出哪些改变?提前谢谢。

2 个答案:

答案 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不兼容,那么您没有为您正在使用的函数提供足够的参数。