F#中如何在模式匹配中正确匹配可区分联合类型的目标分支
F#模式匹配问题修正
你的问题核心是错误地将模式匹配的变量绑定当成了值比较。在F#的模式匹配中,| x1 -> 不是判断当前值是否等于外部的x1变量,而是把当前匹配的值绑定到一个新的同名变量上,导致第一个分支永远会被触发,不管实际值是什么。
修正后的代码
type pos = int*int type value = Red | Green | Blue | Yellow | Black type piece = value*pos type state = piece list let nextColor (v:value) : value = match v with | Red -> Green | Green -> Blue | Blue -> Yellow | Yellow -> Black | Black -> Black let testColor (column: state) : state = let (x1, pos1) = column[0] let (x2, pos2) = column[1] let (x3, pos3) = column[2] match x2 with | _ when x2 = x1 -> [(nextColor x1, pos1); (x3, pos2)] | _ when x2 = x3 -> [(x1, pos1); (nextColor x2, pos2)] | _ -> column
关键修改点
- 用
when守卫实现值比较:
把原来的| x1 ->改成| _ when x2 = x1 ->,这样才是真正判断x2的值是否等于外部变量x1的内容,而不是创建新变量。 - 简化位置解构:
不需要单独拆分pos的两个整数,直接绑定到pos1/pos2/pos3,让代码更简洁。 - 优化列表构造:
用[a; b]直接构造列表,比[a]@[b]更高效,也是F#的惯用写法。
测试验证
输入:
[(Red,(0,0));(Green,(1,0));(Green,(2,0))]
此时x2 = Green,x3 = Green,会匹配第二个分支,输出:
[(Red, (0, 0)); (Blue, (1, 0))]
完全符合你的预期。
内容的提问来源于stack exchange,提问作者morten
相关产品推荐
相关产品推荐

