为什么在识别的指定值上没有模式匹配
当我尝试对名为target的值进行模式匹配时收到警告:
[<Test>]
let ``set center cell to alive``() =
// Setup
let target = (2,2)
let grid = createGrid 9 |> Map.map (fun k v ->
match k with
| target -> { v with Status=Alive }
| _ -> v)
// Test
let center = grid |> getStatus (2,2)
// Verify
center |> should equal Alive
警告指向:
| target -> { v with Status=Alive }
| _ -> v)
特别是:
| _ -> v)
警告是:
永远不会达到这条规则。
这迫使我不使用目标,而是对值进行硬编码以解决警告:
[<Test>]
let ``set center cell to alive``() =
// Setup
let grid = createGrid 9 |> Map.map (fun k v ->
match k with
| (2,2) -> { v with Status=Alive }
| _ -> v)
// Test
let center = grid |> getStatus (2,2)
// Verify
center |> should equal Alive
有人可以解释为什么我不能这样做吗?
完整代码:
type Status = Alive | Dead
type Cell = { X:int; Y:int; Status:Status }
let isNeighbor cell1 cell2 =
let isAbsNeighbor v1 v2 =
match abs (v1 - v2) with
| 0 | 1 -> true
| _ -> false
let isValueNeighbor v1 v2 =
match v1 >= 0
&& v2 >= 0 with
| true -> isAbsNeighbor v1 v2
| _ -> isAbsNeighbor v2 v1
match cell1.X <> cell2.X
|| cell1.Y <> cell2.Y with
| true -> isValueNeighbor cell1.X cell2.X
&& isValueNeighbor cell1.Y cell2.Y
| _ -> false
let createGrid rowCount =
[for x in 1..rowCount do
for y in 1..rowCount do
yield { X=x; Y=y; Status=Dead } ]
|> List.map (fun c -> (c.X, c.Y), { X=c.X; Y=c.Y; Status=Dead })
|> Map.ofList
let getStatus coordinate (grid:Map<(int * int), Cell>) =
match grid.TryFind coordinate with
| Some cell -> cell.Status
| None -> Dead
答案 0 :(得分:8)
在match
表达式中,规则
match k with
| target -> { v with Status=Alive }
无条件地匹配并将k
绑定到名称target
,该名称隐藏现有定义。这意味着永远不会达到以下条款。您可以使用条件匹配:
match k with
| t when t = target -> { v with Status = Alive }
| _ -> v
答案 1 :(得分:0)
根据Pattern Matching,target
是变量模式,因此它会隐藏原始目标值。
模式匹配对于匹配对象的解构非常有用,因为简单的测试if-else
是可取的(在我看来)。
如果要测试多个案例,则用于模式匹配的用例。您可以使用when guard代替active patterns:
let (|Eq|_|) expected actual =
if expected = actual then Some()
else None
let target = (2,2)
let attempt = (3,2)
match attempt with
| Eq target -> Some "Bulls eye"
| (2, _) -> Some "Almost"
| t when fst t > 20 -> Some "Quite the contrary"
| _ -> None