我有一个函数连接两个字符串,并在它们之间放置一个逗号和空格并返回它.我不能打印结果.
let concat first second =
first + ", " + second
printfn "%s" concat "hello" "world"
Run Code Online (Sandbox Code Playgroud)
类型不匹配.期待'字符串 - >'a - >'b - >'c'但给出'字符串 - >单位'类型'' - >'b - >'c'与类型'单位'不匹配(使用外部F#编译器)
这个表达式应该有'string'类型,但这里有'string - > string - > string'类型
如何正确打印返回的字符串?
编辑:似乎我需要围绕调用concat的括号.为什么需要这个?
let concat first second =
first + ", " + second
printfn "%s" (concat "hello" "world")
Run Code Online (Sandbox Code Playgroud)
Robert Nielsen的回答是正确的,但让我尝试一种不同的方式来解释它,因为如果你是F#的新手,可能很难理解如下的表达式:
(((printfn "%s") concat) "hello") "world"
Run Code Online (Sandbox Code Playgroud)
所以想一想:在F#中,函数可以作为输入传递给其他函数.例如,您可以将concat函数作为输入传递给List.reduce:
List.reduce concat ["one"; "two"; "three"]
// Returns "one, two, three"
Run Code Online (Sandbox Code Playgroud)
现在,您可以通过两种方式阅读此内容.函数调用可以保留优先级或右优先级.即,如果函数调用具有正确的优先级,那么该["one"; "two"; "three"]列表将被视为该concat函数的第一个参数(因为它是最右边的,因此具有优先权).或者如果函数调用具有优先权,那么该列表将是List.reduce函数的第二个参数,并且该concat函数将是第一个参数.F#使后者(左优先)成为默认值:在没有括号的情况下,函数名称后面的所有内容都被认为是该函数的参数.所以以下内容:
printfn "%s" concat "hello" "world"
Run Code Online (Sandbox Code Playgroud)
读作:" printfn使用四个参数调用函数:字符串,函数和另外两个字符串".如果要将字符串"hello"和"world"作为参数concat,则必须添加括号,以便F#将以concat更高的优先级解析调用(如您已经发现的那样):
printfn "%s" (concat "hello" "world")
Run Code Online (Sandbox Code Playgroud)
这被解读为:" concat使用两个字符串作为参数调用函数,然后获取该函数调用的结果并将其作为第二个参数传递给printfn".
但想想这个:如果默认是另一种方式,并且函数调用具有正确的优先级 - 您如何将括号放入该List.reduce示例中以使其按您想要的方式工作?你想要的是" List.reduce用两个参数调用:第一个是函数,第二个是字符串列表." 但是你如何为此添加括号:
List.reduce concat ["one"; "two"; "three"]
Run Code Online (Sandbox Code Playgroud)
得到那个结果?嗯,这会工作:
(List.reduce concat) ["one"; "two"; "three"]
Run Code Online (Sandbox Code Playgroud)
但在我看来,这将令人困惑.要理解这个表达式,你必须要了解F#currying是如何工作的,这是一个通常需要一段时间才能解决问题的概念.对于左优先级函数调用,表达式someFunction a b c总是表示" someFunction使用三个参数调用",无论这三个参数中的任何一个是函数.
我希望这个冗长的解释能帮助你更好地理解F#函数调用.
| 归档时间: |
|
| 查看次数: |
196 次 |
| 最近记录: |