F#功能组合有两个参数功能

时间:2014-08-04 04:12:13

标签: f#

在我查看微软帮助中的示例之前,我认为我理解了函数组合。它显示了以下示例:

let appendString (string1:string) (string2:string) = string1 + string2
let appendExtension fileExtension = appendString "." >> appendString fileExtension
let fileName = appendExtension "myfile" "txt"

appendExtension的类型为string -> (string -> string)。这似乎是正确的,因为它是部分应用程序。但缺少的参数是第一个而不是第二个。这怎么可能?

如果我在没有作文的情况下写appendExtension,我会这样做:

let appendExtension name extension = appendString (appendString name ".") extension

括号中的代码看起来像组合的第一部分,但它是appendString的完整应用程序。< 因此,我们删除其中一个参数以进行部分应用,从而实现一个功能。 但第一个参数被删除而不是第二个参数。 这怎么可能?

2 个答案:

答案 0 :(得分:1)

fileExtension中的appendExtension参数未命名 - 确实是filename!但当然这并不重要,因为名字对程序员来说才真正重要。

如果有疑问,请逐步删除违规表达式:

appendExtension "myfile" "txt" =
(appendExtension "myfile") "txt" =
// definition of appendExtension - insert "myfile" into `fileExtension` ..
(appendString "." >> appendString "myfile") "txt" =
// expand ">>" into "|>" IMHO easiest
"txt" |> appString "." |> appendString "myfile" =
// insert in first
appString "." "txt" |> appendString "myfile" =
// apply first
".txt" |> appendString "myfile" =
// insert and apply second
"myfile.txt"

答案 1 :(得分:1)

使用最简单的构图理解,即:

(f >> g) x = g(f(x))

我们有

let appendExtension s = appendString "." >> appendString s

appendExtension "myfile" "txt"
=> (appendString "." >> appendString "myfile") "txt"
=> appendString "myfile" (appendString "." "txt")
=> appendString "myfile" (".txt")
=> "myfile.txt"

已经由Carsten解释过。

你在围绕部分申请的问题中提出了一些很好的观点,我同意你的观点,这个例子可能是一个可怕的例子,或者至少是一个令人困惑的例子。当我想到部分应用时,我会期待(也许我是唯一一个有这种感觉的人),那个

appendExtension ext

会生成一个将扩展名ext添加到字符串的函数!如果是这种情况,我可以说:

let addTxt = appendExtension "txt"

所以

addTxt "myfile"
=> "myfile.txt"

类似地,

appendString s

应生成将s添加到其参数的函数。在这个世界观,我更喜欢,但可能没有其他人这样做,我们有这个推导:

(appendExtension "txt") "myfile"
=> (appendString "." >> appendString "txt") "myfile"
=> appendString "txt" (appendString "." "myfile")
=> appendString "txt" ("myfile.")
=> "myfile.txt"

我想,无论哪种方式都有效。我喜欢我的方式,因为部分应用程序更有意义。那么我们如何理解这个令人困惑的微软例子呢?他们写的时候就是这个想法:

appendString s

他们的意思是这是一个向s 附加内容的函数,而不是将s附加到某个函数的函数。恕我直言,这是一种阅读英语的可怕而混乱的方式。他们期待

appendString "dog"

表示附加到“dog”的函数,但它看起来附加“dog”的函数。他们为什么这么做?也许他们想要

appendString "dog" "house"

读起来就像是从左到右追加。他们想让它看起来像一个双参数函数。 Ewwww。也许这就是惯例,但是在考虑部分应用时,应该注意这一点。