这是我的问题...我不明白为什么这对我不起作用:)
更具体地说,我有一个获取文件功能(不是问题,但欢迎反馈):
type DirectoryOptions = Directory of string * Option<SearchOption>
type SearchOptions =
| SearchSubDirectories
| SearchCurrentDirectory
let WithExtensionIn extlist filename =
let fileext = Path.GetExtension filename
extlist |> Seq.exists (fun e -> e = fileext)
let GetFiles dir extlist =
match dir with
| Some diroptions ->
let directoryname, suboptions = diroptions
match suboptions with
| Some SearchSubDirectories | None ->
Directory.GetFiles(directoryname, "*.*", SearchOption.AllDirectories)
|> Seq.filter (WithExtensionIn extlist)
| Some SearchCurrentDirectory ->
Directory.GetFiles(directoryname, "*.*", SearchOption.TopDirectoryOnly)
|> Seq.filter (WithExtensionIn extlist)
| None ->
Directory.GetFiles(Directory.GetCurrentDirectory(), "*.*", SearchOption.AllDirectories)
|> Seq.filter (WithExtensionIn extlist)
我想将其组成一个获取重复文件函数。我可能做不到,但我正在努力让我的头脑进入功能性思维模式。我目前的尝试,根据我的理解应该有效,但没有成功。这意味着我的理解是错误的,我需要一些关于如何解决这个问题的帮助/澄清。我的理解是,在函数组合中,最里面的函数可以有 n 个输入参数,但只有一个输出,而包装它的其余函数只能有 1 个输入和 1 个输出。我不完全确定在 F# 的组合上下文中如何解释第一个函数(可能是一个不好的词),因为没有明显的输入/输出。我相信这是柯里化(Currying)的直接影响。
这是我当前的尝试:
let GetDuplicateFiles =
let LengthAndExtension file =
//this is faked for simplicity
(12, ".htm")
let GroupSizeGreaterThanOne group =
let _, values = group
Seq.length values > 1
let content file =
//again faked
()
let groups items =
snd items
GetFiles
>> Seq.groupBy LengthAndExtension
>> Seq.filter GroupSizeGreaterThanOne
>> Seq.collect groups
>> Seq.groupBy content
>> Seq.filter GroupSizeGreaterThanOne
>> Seq.collect groups
这给了我 Seq.groupBy LengthAndExtension 上的编译错误 错误是类型 ''b -> seq' 与类型 'seq<'a>' 不兼容
欢迎任何想法/反馈。我想我正在寻找一个啊哈时刻,如果你明白我的意思
最佳答案
正向组合 (>>
) 创建一个新函数,将第一个函数的输出作为第二个函数的输入。
签名揭示了问题:( >> ) : ('T1 -> 'T2) -> ('T2 -> 'T3) -> 'T1 -> 'T3
它接受两个函数,每个函数都有一个参数。但是 GetFiles 需要两个参数。一个快速的解决方案是更改 GetFiles
以采用元组:let GetFiles (dir, extlist) = ...
。
关于.net - F# - 不理解函数组合(将获取文件函数转换为获取重复文件函数),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8495736/