当谈到F#的许多领域时,我仍然是一个新手。我更多地出于好奇而提出这个问题,而不是出于实际的业务需要。是否有任何方法可以匹配列表中的第一个n项目,而不管它们出现的顺序是什么?为了澄清,请看下面的例子:任何订单中的匹配列表项目
type MyEnum =
| Foo of int
| Bar of float
| Baz of string
let list = [ Foo 1 ; Bar 1.0 ; Baz "1" ]
现在,假设我想打电话给some_func
如果在列表中的前两项是Foo
和Bar
,以任意顺序。这是很容易只匹配两个可能的排列:
let result =
match list with
| Foo n :: Bar x :: _
| Bar x :: Foo n :: _ -> some_func n x
| _ -> failwith "First 2 items must be Foo and Bar"
但是,如果我需要调用一个函数如果第3项是Foo
,Bar
以任意顺序Baz
什么?使用上述相同的技术将要求我写出所有6个不同的排列(或n!对于n项目)。理想情况下,我想能够做到沿此线的东西:
let result =
match list with
| (AnyOrder [ Foo n ; Bar x ; Baz s ]) :: _ -> some_func n x s
| _ -> failwith "First 3 items must be Foo, Bar, and Baz"
有没有办法用某种形式的active pattern做到这一点,而无需进行硬编码的不同排列?
不错。我喜欢非常简单的方法。唯一有点恼人的是,匹配表达式*中的列表有*要排序 - 'AnyOrderOfFirst 3 [Bar x; Foo n;巴兹]'永远不会匹配。我也喜欢你可以做一些事情,比如'前4个中的2个是'Foo''s'和'AnyOrderOfFirst 4 [Foo a; Foo b; _; _]',但要用'Bar'做同样的事情,你必须写出3种不同的情况。 – 2014-11-06 13:20:15
是的,这是这个解决方案的缺点:匹配中的列表务必排序,排序顺序是在DU中声明TAG的顺序。这应该始终同步。 – Gustavo 2014-11-06 13:26:55