类型与printfn不匹配

用户名

我有一个连接两个字符串的函数,并在它们之间放置一个逗号和空格并返回该字符串。我无法打印结果。

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] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章