简单的问题。
我有一个函数,它接受两个字符串和一个int,并返回一个带有n
行的新字符串,并在两个输入字符串之间交替。
let rec f s1 s2 n = function
| s1 when n > 0 -> s1 + "\n" + f s2 s1 (n-1)
| s2 when n > 0 -> s2 + "\n" + f s1 s2 (n-1)
调用它
f "ab" "cd" 4
应该返回ab\ncd\nab\ncd
我目前在方法string -> string -> int -> (string -> 'a)
中收到错误,我不确定原因。任何提示?
更新:
事实证明,它是由使用匿名function
引起的。将其更改为match
表达式可以解决它:
let rec f s1 s2 n =
match s1 with
| _ when n <= 0 -> ""
| s1 when n > 0 -> s1 + "\n" + f s2 s1 (n-1)
| s2 when n > 0 -> s2 + "\n" + f s1 s2 (n-1)
更新2:上述功能可能是朝着正确方向迈出的一步,但正如TheQuickBrownFox所指出的那样,下面的实现是正确的。
let rec f s1 s2 n =
if n <= 0 then ""
else s1 + "\n" + f s2 s1 (n-1)
答案 0 :(得分:3)
function
关键字创建一个带有一个参数的新匿名函数(或lambda),并直接进入模式匹配。
因此,您的f
函数需要s1
,s2
和n
,然后返回另一个函数作为值。这和写这个一样:
let rec f s1 s2 n =
fun x ->
match x with
| s1 when n > 0 -> s1 + "\n" + f s2 s1 (n-1)
| s2 when n > 0 -> s2 + "\n" + f s1 s2 (n-1)
我不清楚你的功能是怎么做的,所以我不能建议你修复。我建议暂时不要使用function
关键字。尝试以这种形式编写此函数,看看它是否有帮助:
let rec f s1 s2 n =
match ... with
...
<强>更新强>
在您更新的实现中,您实际上根本没有使用模式匹配。模式部分被有效地丢弃,when
子句正在完成所有工作。此外,由于n <= 0
或n > 0
,无法到达最后一个分支。您的新功能可以更简单地编写:
let rec f s1 s2 n =
if n <= 0 then ""
else s1 + "\n" + f s2 s1 (n-1)