如何匹配一个值的多个副本? [英] How to match multiple copies of a value?
问题描述
F#的模式匹配功能非常强大,因此编写起来很自然:
F#'s pattern matching is very powerful so it felt natural to write:
match (tuple1, tuple2) with
| ((a, a), (a, a)) -> "all values are the same"
| ((a, b), (a, b)) -> "tuples are the same"
| ((a, b), (a, c)) -> "first values are the same"
// etc
但是,第一个模式匹配会导致编译器错误:
However, the first pattern match gives a compiler error:
'a' is bound twice in this pattern
是否有比以下方法更清洁的方法?
Is there a cleaner way to do it than the following?
match (tuple1, tuple2) with
| ((a, b), (c, d)) when a = b && b = c && c = d -> "all values are the same"
| ((a, b), (c, d)) when a = c && b = d -> "tuples are the same"
| ((a, b), (c, d)) when a = c -> "first values are the same"
// etc
推荐答案
这是F#的活动模式"的完美用例.您可以这样定义其中的几个:
This is a perfect use case for F#'s "active patterns". You can define a couple of them like this:
let (|Same|_|) (a, b) =
if a = b then Some a else None
let (|FstEqual|_|) ((a, _), (c, _)) =
if a = c then Some a else None
然后清理与它们匹配的模式;注意第一种情况(所有值都相等)如何使用嵌套的Same
模式检查元组的第一和第二个元素是否相等:
And then clean up your pattern matching with them; note how the first case (where all values are equal) uses the nested Same
pattern to check that the first and second elements of the tuple are equal:
match tuple1, tuple2 with
| Same (Same x) ->
"all values are the same"
| Same (x, y) ->
"tuples are the same"
| FstEqual a ->
"first values are the same"
| _ ->
failwith "TODO"
性能提示:我想用inline
标记类似这样的简单活动模式-由于活动模式中的逻辑很简单(仅包含几条IL指令),因此可以内联它们并避免代码开销函数调用.
Performance tip: I like to mark simple active patterns like these with inline
-- since the logic within the active patterns is simple (just a few IL instructions), it makes sense to inline them and avoid the overhead of a function call.
这篇关于如何匹配一个值的多个副本?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!