我有一个连接两个字符串的函数,并在它们之间放置一个逗号和空格并返回该字符串。我无法打印结果。
let concat first second =
first + ", " + second
printfn "%s" concat "hello" "world"
类型不匹配。预期为'string->'a->'b->'c'但给定了'string-> unit'类型'a->'b->'c'与类型'unit'不匹配(使用外部F#编译器)
该表达式应具有'string'类型,但此处具有'string-> string-> string'类型
如何正确打印返回的字符串?
编辑:似乎我需要括号包围concat的电话。为什么需要这个?
let concat first second =
first + ", " + second
printfn "%s" (concat "hello" "world")
罗伯特·尼尔森(Robert Nielsen)的答案是正确的,但让我尝试另一种解释方式,因为如果您不熟悉F#,可能很难理解如下表达式:
(((printfn "%s") concat) "hello") "world"
因此,请这样考虑:在F#中,函数可以作为输入传递给其他函数。例如,您可以将concat
函数作为输入传递给List.reduce
:
List.reduce concat ["one"; "two"; "three"]
// Returns "one, two, three"
现在,有两种阅读方法。函数调用可以具有左优先级,也可以具有右优先级。即,如果函数调用具有正确的优先级,则该["one"; "two"; "three"]
列表将被视为concat
函数的第一个参数(因为它在最右边,因此具有优先级)。或者,如果函数调用的优先级最高,则该列表将是List.reduce
函数的第二个参数,而concat
函数将是第一个参数。F#将后者(左优先)作为默认值:在没有括号的情况下,函数名称之后的所有内容均视为该函数的参数。因此,以下内容:
printfn "%s" concat "hello" "world"
读作如下:“printfn
使用四个参数调用函数:一个字符串,一个函数和另外两个字符串”。如果希望将字符串“ hello”和“ world”作为的参数concat
,则必须添加括号,以便F#可以concat
以更高的优先级解析调用(如您所知):
printfn "%s" (concat "hello" "world")
读作如下:“concat
以两个字符串作为参数调用函数,然后获取该函数调用的结果,并将其作为第二个参数传递给printfn
”。
但是请考虑一下:如果默认设置是相反的,并且函数调用具有正确的优先级-您如何在该List.reduce
示例中加上括号以使其按您希望的方式工作?您想要的是“List.reduce
使用两个参数进行调用:第一个参数是一个函数,第二个参数是字符串列表”。但是,如何在此添加括号:
List.reduce concat ["one"; "two"; "three"]
得到那个结果?好吧,这会起作用:
(List.reduce concat) ["one"; "two"; "three"]
但是我认为这将令人困惑。要理解该表达方式,您必须了解F#currying的工作原理,而这是一个通常需要花费一些时间才能扎根的概念。对于左优先函数调用,无论这三个参数中的任何一个是否为函数,该表达式someFunction a b c
始终表示“someFunction
具有三个参数的调用”。
我希望这个冗长的说明可以帮助您更好地理解F#函数调用。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句