簡體   English   中英

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

[英]F# Ignore a pattern in pattern match

我可能會以錯誤的方式思考這個問題,但我想忽略Some案例以外的任何案例。 這是我正在使用的一些示例代碼| _ -> ignore | _ -> 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<unit>async計算表達式中。 所以你應該用return ()替換ignore (其中()是單位值),以便所有分支返回相同的類型:

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和/或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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM