F#递归模式匹配方法重写参数



在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
| ...

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

匹配中的pxpy不是参数中给定的
它们是匹配的ij,px和py只是您选择给它们的名称(遮蔽原始px和py)

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

您应该考虑一些注释和答案。也就是说,当情况很复杂,你最终使用了很多防护装置时,研究活动模式可能是个好主意。请参阅下面的示例,该示例排除了相等性检查。它的优点是使代码更可读(通常)。

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:单位=()
2 0 1 0 val-it:单位=()

最新更新