F#为什么我会得到这种返回类型?

时间:2017-10-15 08:06:46

标签: f#

简单的问题。

我有一个函数,它接受两个字符串和一个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)

1 个答案:

答案 0 :(得分:3)

function关键字创建一个带有一个参数的新匿名函数(或lambda),并直接进入模式匹配。

因此,您的f函数需要s1s2n,然后返回另一个函数作为值。这和写这个一样:

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 <= 0n > 0,无法到达最后一个分支。您的新功能可以更简单地编写:

let rec f s1 s2 n = 
    if n <= 0 then ""
    else s1 + "\n" + f s2 s1 (n-1)