F#递归模式匹配方法覆盖参数

时间:2016-07-22 12:47:39

标签: recursion f# arguments pattern-matching

在F#控制台应用程序中构建snake时,我使用以下代码更新控制台窗口。

//Sets the next character in accumulator
//(i, j) are the coordinates of the game
//(px, py) are the coordinates of snake's head
let rec setConsoleChar acc i j px py =
    if i=px && j=py then
        setConsoleChar (acc+"H") (i+1) j px py
    else
        match i, j with
        | ...

但我无法帮助但是想知道(px, py)的比较是否也可以在模式匹配块中。我尝试使用以下代码,但是在点击时,(i, j)指针更改为指向(px, py),这导致返回值错误,只包含' H

match i, j with
| px, py -> setConsoleChar (acc+"H") (i+1) j px py
| ...

PS:如果有人知道简化事情的方法,请分享。

2 个答案:

答案 0 :(得分:0)

匹配中的pxpy不是参数中给出的。{
} 它们是匹配的ij,而px和py只是您选择给它们的名称(阴影原始的px和py)

结果它的i和j伪装成px和py,你给了递归调用而不是"真正的" px和py。

答案 1 :(得分:0)

您应该考虑一些评论和答案。也就是说,当情况变得复杂并且你最后使用了大量守卫时,最好调查一下active patterns。请参阅下面的示例,了解相等性检查。它的优点是使代码更具可读性(通常)。

let (|MATCH|NOMATCH|) (i,j,px,py) = 
        if i = px && j = py then MATCH
        else
            NOMATCH

let setConsoleChar  (i,j,px,py) =
        match (i,j,px,py) with
        | MATCH -> printfn "%A %A %A %A"  (i+1) j px py
        | NOMATCH -> printfn "%A" "Wot???"


setConsoleChar (1,2,3, 4)
setConsoleChar  (1, 0, 1, 0)
  

“WOT ???” val it:unit =()
   2 0 1 0 val it:unit =()