F# 忽略模式匹配中的模式

F# Ignore a pattern in pattern match

我可能以错误的方式思考这个问题,但我想忽略 Some 案例以外的任何案例。这是我正在使用的一些示例代码 | _ -> ignore 但这似乎是错误的。有没有更好或更惯用的方法来做到这一点?我正在将一些 OOP C# 代码转换为 F#,可能会出现错误。

match solarSystem.MinerCoords |> Map.tryFind minerId with
| Some currentMinerCoords ->
    match solarSystem.Minables |> Map.tryFind currentMinerCoords with
    | Some _ ->
        do! GetMinerActor(minerId).StopMining() |> Async.AwaitTask
    | _ -> ignore
| _ -> ignore

您似乎在 async 计算表达式中 returns Async<unit>。所以你应该用 return () 替换 ignore (其中 () 是单位值)以便所有分支 return 相同的类型:

match solarSystem.MinerCoords |> Map.tryFind minerId with
| Some currentMinerCoords ->
    match solarSystem.Minables |> Map.tryFind currentMinerCoords with
    | Some _ ->
        do! GetMinerActor(minerId).StopMining() |> Async.AwaitTask
    | _ -> return ()
| _ -> return ()

编辑:显示整个异步块的简化版本,以及如何继续 运行 之后的更多代码:

async {
    match Some 1 with
    | Some a ->
        printfn "Maybe do this"
        do! Async.Sleep 500
    | _ -> ()

    printfn "Always do this"
    do! Async.Sleep 500
    printfn "Finished" }

你可以让每个分支产生一个异步,然后你就可以执行它了。像这样:

let dummyAsync = async { return () }
let theAsync =
    match solarSystem.MinerCoords |> Map.tryFind minerId with
    | Some currentMinerCoords when solarSystem.Minables |> Map.tryFind currentMinerCoords |> Option.isSome ->
        GetMinerActor(minerId).StopMining() |> Async.AwaitTask
    | _ ->
        dummyAsync
do! theAsync

注意使用 when 关键字删除一个不必要的分支。

更习惯地说,当您以嵌套方式匹配多个选项值时,您应该使用函数 Option.bind and/or Option.map:

let dummyAsync = async { return () }
let theAsync =
    solarSystem.MinerCoords
    |> Map.tryFind minerId
    |> Option.bind (fun currentMinerCoords -> solarSystem.Minables |> Map.tryFind currentMinerCoords)
    |> Option.map (fun _ -> GetMinerActor(minerId).StopMining() |> Async.AwaitTask)
    |> Option.defaultValue dummyAsync
do! theAsync