2017-12-03 315 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