我刚刚开始使用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
这怎么可能?
答案 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