F#模式匹配出错了

时间:2017-12-03 06:58:57

标签: f# pattern-matching

我刚刚开始使用F#,所以这可能是一个微不足道的问题,但我无法理解为什么我的代码中的模式匹配就像它一样。

代码的快速解释:
func calcNextMatch 应该递归列表,如果2个元素相等,则应将它们加在一起。 最后,func应返回一个数字,该数字是与列表中下一个数字匹配的所有数字的加法。
f.ex. [1; 3; 2; 2; 5]应该返回4

代码:

let rec printList l =
    match l with
    | head :: tail -> printf "%d " head; printList tail
    | [] -> printfn ""

let rec calcNextMatch list =
    printList list
    match list with
    | [] -> 0
    | _ :: tail ->            
        printList tail
        let h = Seq.head list
        let t = Seq.tryHead tail
        printfn "h: %i" h
        printfn "t: %O" t
        match t with
        | Some h -> 
            printfn "TAIL t: %i is equal to HEAD h: %i" t.Value h
            printfn "Calculation is: %i" (t.Value + h)
            (t.Value + h) + calcNextMatch tail
        | _ -> calcNextMatch tail

let sequence = [ 1;3;2;2;5 ]
let run = calcNextMatch sequence

当我运行此代码时,问题是模式匹配 不像我期望的那样工作。 f.ex运行脚本的打印输出。

h: 1
t: Some(3)
TAIL t: 3 is equal to HEAD h: 3

这意味着F#匹配

match t with
        | Some h -> 

在t = Some(3)且h = 1的情况下 转换为

match 3 with
        | Some 1 -> 

我不明白。 匹配前的打印将t和h的值表示为 3 1 ,但在模式匹配中, h 的值已更改为 3
这怎么可能?

1 个答案:

答案 0 :(得分:3)

您只能对常量文字进行模式匹配,否则值的限制就好像是一个新的let-binding。

在这些情况下,您通常会添加when条件:

    match t with
    | Some x when x = h -> 

另请注意,您可以进一步使用模式匹配来简化代码,例如:

| _ :: tail ->            
    printList tail
    let h = Seq.head list

你可以写:

| h :: tail ->            
    printList tail

还有这一部分:

| _ :: tail ->            
    printList tail
    let h = Seq.head list
    let t = Seq.tryHead tail
    printfn "h: %i" h
    printfn "t: %O" t
    match t with
    | Some h -> 
        printfn "TAIL t: %i is equal to HEAD h: %i" t.Value h
        printfn "Calculation is: %i" (t.Value + h)
        (t.Value + h) + calcNextMatch tail

变为:

| h :: tail ->            
    printList tail
    //printfn "h: %i" h
    //printfn "t: %O" t
    match tail with
    | t::_ when t = h -> 
        printfn "TAIL t: %i is equal to HEAD h: %i" t h
        printfn "Calculation is: %i" (t + h)
        (t + h) + calcNextMatch tail

你可以将所有比赛统一在一起,这样你的整个功能就变成了:

let rec calcNextMatch list =
    printList list
    match list with
    | [] -> 0
    | h::x::tail when x = h -> x + h + calcNextMatch (x::tail)
    | _::tail -> calcNextMatch tail

最后,当您完成调试后,您可以删除打印件,因为您的函数的最后一个参数是您匹配的参数,您可以使用关键字function,也可以使用{ {1}}模式以避免重建列表:

as