F# 类型与printfn不匹配
我有一个函数,它连接两个字符串,并在它们之间放置逗号和空格,然后返回。但是我不能打印结果F# 类型与printfn不匹配,f#,F#,我有一个函数,它连接两个字符串,并在它们之间放置逗号和空格,然后返回。但是我不能打印结果 let concat first second = first + ", " + second printfn "%s" concat "hello" "world" 类型不匹配。应为'string->'a->'b->'c',但给定'string->unit',类型'a->'b->'c'与类型'unit'不匹配(使用外部F编译器) 此表达式应具有“string”类型,但此处 具有“字符串->字
let concat first second =
first + ", " + second
printfn "%s" concat "hello" "world"
类型不匹配。应为'string->'a->'b->'c',但给定'string->unit',类型'a->'b->'c'与类型'unit'不匹配(使用外部F编译器)
此表达式应具有“string”类型,但此处
具有“字符串->字符串->字符串”类型
如何正确打印返回的字符串
编辑:看来我需要用括号括住对concat的调用。为什么需要这样做
let concat first second =
first + ", " + second
printfn "%s" (concat "hello" "world")
由于F-sharp运算符的优先级: 编辑:您可以将其视为旋转
(((printfn "%s") concat) "hello") "world"
进入
罗伯特·尼尔森的答案是正确的,但让我试着用另一种方式来解释,因为如果你是F#的新手,可能很难理解这样的表达:
(((printfn "%s") concat) "hello") "world"
所以可以这样想:在F#中,函数可以作为输入传递给其他函数。例如,您可以将concat
函数作为输入传递给列表。reduce
:
List.reduce concat ["one"; "two"; "three"]
// Returns "one, two, three"
现在,有两种方法可以让你阅读。函数调用可以具有左优先级,也可以具有右优先级。也就是说,如果函数调用具有正确的优先级,那么[“一”;“二”;“三”]
列表将被视为concat
函数的第一个参数(因为它是最右边的,因此具有优先级)。或者,如果函数调用具有左优先级,则该列表将是list.reduce
函数的第二个参数,而concat
函数将是第一个参数。F#使后一个(左优先)成为默认值:在没有括号的情况下,函数名后面的所有内容都被视为该函数的参数。因此,以下是:
printfn "%s" concat "hello" "world"
读作:“使用四个参数调用printfn
函数:一个字符串、一个函数和另外两个字符串”。如果希望字符串“hello”和“world”作为concat
的参数,则必须添加括号,以便F#以更高的优先级解析concat
调用(正如您已经发现的):
这被理解为:“使用两个字符串作为参数调用concat
函数,然后将该函数调用的结果作为第二个参数传递给printfn
”
但是请想一想:如果默认值是另一种情况,并且函数调用具有正确的优先级,那么如何将括号放入列表中。减少示例以使其按您想要的方式工作?您需要的是“调用List.reduce
,其中包含两个参数:第一个是函数,第二个是字符串列表。”但如何在其中添加括号:
List.reduce concat ["one"; "two"; "three"]
为了得到那个结果?好吧,这会有用的:
(List.reduce concat) ["one"; "two"; "three"]
但在我看来,这会令人困惑。要理解这个表达方式,你必须理解F#currying是如何工作的,这是一个通常需要花一点时间才能理解的概念。而对于左优先函数调用,表达式someFunction a b c
始终表示“调用someFunction
,使用三个参数”,无论这三个参数中是否有一个是函数
我希望这个冗长的解释能帮助您更好地理解F#函数调用。错误告诉您:printfn在抱怨-它得到了%s”
现在需要一个字符串
但是得到了一个包含多个参数的函数:这个表达式应该有'string'类型,但是这里有'string->string->string'
你的最后一个例子可能应该是(List.reduce concat)[“one”;“two”;“three”]
尽可能清晰。我想到了,但是决定,对于一个可能还没有摸索过咖喱概念的F#新手来说,这可能会让他们感到困惑,而不是帮助他们。编辑:改变了我的想法。你说得对,我应该展示一下它是如何工作的。
List.reduce concat ["one"; "two"; "three"]
(List.reduce concat) ["one"; "two"; "three"]