有没有办法重写F#中这个match语句中的when子句



我有一个"子状态":

type SubState =
| DoingA
| DoingB
| AFewMore

和一个主要状态:

type State =
| Initializing
| DoingStuff of SubState
| DoingNothing

然后我在匹配语句中使用该状态:

let state : State = ... 
match anotherState with
| hello -> ()
| hello when state = Initializing -> ()
| hello when state = DoingStuff -> ()   <- won't compile
| hello when state = DoingStuff _-> ()  <- won't compile either

所以我必须在我的州里添加一个助手:

type State =
| Initializing
| DoingStuff of SubState
| DoingNothing
member this.IsDoingStuff =
match this with
| DoingStuff _ -> true
| _ -> false

然后我可以用进行我的主要比赛

match anotherState with
| hello -> ()
| hello when state = Initializing -> ()
| hello when state.IsDoingStuff -> () <- this works

但我真的很喜欢

| hello when state = DoingStuffAndIDontCareAboutTheSubState -> ()

有没有一种很好的语法方法来满足when条件并忽略"DoingStuff"的值?

我知道我可以做:

match anotherState, state with
| hello, DoingStuff _ -> 

但在许多情况下,我不需要第二个值,所以我试图找到一个可以保留when语句的解决方案。

不需要使用匹配表达式。您可以在这里使用正常的标识符模式匹配:

let state anotherState =
match anotherState with
| Initializing -> ()
| DoingStuff _ -> ()
| DoingNothing ->

你也可以嵌套这些并检查子状态:

let state anotherState =
match anotherState with
| Initializing -> ()
| DoingStuff DoingA -> ()
| DoingStuff DoingB -> ()
| DoingStuff AFewMore -> ()
| DoingNothing ->

如果你想在匹配案例中使用一个表达式,匹配表达式是有用的,例如,假设你有这样的:

type Foo =
| Bar
| Baz of int
let state foo =
match foo with
| Bar -> ()
| Baz 0 -> ()
| Baz 1 -> ()
| Baz i when i < 10 -> ()
| Baz _ -> ()

您正试图将when用于应该使用模式匹配的东西;最后一个例子是实现这一点的惯用方法:

match anotherState, state with
| hello, DoingStuff _ -> 

when适用于不能这样做的情况,并且会严重损害编译器进行穷尽性检查的能力。

这一切都是假设您在实际代码中也对anotherState进行模式匹配,否则这不需要成为match的一部分。

最新更新