2016-03-15 57 views
2

爲什麼沒有圖案的分配值匹配認可爲什麼沒有圖案的分配值匹配認可

我收到警告,當我嘗試在值稱爲目標模式匹配:

[<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 

回答

8

match表達式,該規則

match k with 
| target -> { v with Status=Alive } 

無條件匹配並結合k到一個名稱target其陰影的現有定義。這意味着永遠不會達到以下條款。您可以使用條件匹配:

match k with 
| t when t = target -> { v with Status = Alive } 
| _ -> v 
0

根據Pattern Matchingtarget可變模式,所以陰影原目標值。

模式匹配是有用的解構匹配的對象,對於簡單的測試是可取的(在我看來)。

模式匹配的用例是如果你想測試幾個案例。您也可以使用active patterns代替when guard

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