2017-12-03 297 views
3

我刚刚开始使用F#,所以这可能是一个微不足道的问题,但我无法理解为什么我的代码中的模式匹配就像它一样行事。代码的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 f.ex打印输出。

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

这意味着F#已在的情况下匹配

match t with 
     | Some h -> 

其中t =一些(3)和h = 1 其转换为

match 3 with 
     | Some 1 -> 

和我不理解。 匹配状态之前打印吨和h的给和但在值的模式匹配的ħ值已更改为
这是如何实现?

+0

'某些h'声明了一个新的变量'h',与现有变量的值不匹配。 – Mankarse

回答

3

您只能对常量字面值进行匹配模式匹配,否则该值会像有新的绑定一样受限制。

在这种情况下,你做正常的是添加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,也可以使用as模式来避免重新构建列表:

let rec calcNextMatch = function 
    | [] -> 0 
    | h::((x::_) as tail) when x = h -> x + h + calcNextMatch tail 
    | _::tail -> calcNextMatch tail 
+1

感谢您的帮助和全面的解释。我现在明白了。 我还假设这是我不知道F#做的事情。 现在我的算法做它应该做的:-D – ThBlitz