Allow n partitions for ActivePatterns
Active patterns can only have seven partitions (see: http://msdn.microsoft.com/en-us/library/dd233248.aspx)
It would be good if this was a stylistic constraint that could be overridden if desired.
For example, if active patterns are getting used to split up XML nodes meaningfully, you aren't in control of how many nodes sensibly fit into the top level.
What was the F# team aiming for here? Is there a performance based reason why this limit was chosen? Active Patterns are a fantastic invention. Please make them more flexible and less idiomatic.
Tomas: a similar scenario triggered the request. I wanted to extend a C# based AST with F#. We could redo the AST in F#. Thought stream: oh cool, we could use Active Patterns encapsulate a bunch of ugly tests... uh oh... we just hit the limit. It's just a bump in the road that perhaps shouldn't be there. The discovery experience up to there was fun. We were discovering things about a code base we hadn't used before while deriving additional functionality.
Tomas Petricek commented
I can understand why this is not supported (sounds like that could be quite a mess :-)) but I agree this would be very useful.
For example, I was convincing my colleagues to use F# for some AST processing in Phalanger which is written in C# and has a massive AST represented using a class hierarchy (https://github.com/DEVSENSE/Phalanger/tree/master/Source/Core/Compiler/AST).
Implementing a huge active pattern to wrap the hierarchy might be ugly, but it would be a fairly direct way to integrate the project with some F#.
Mauricio Scheffer commented
It seems the compiler could work around this by nesting ChoiceXofY the same way big tuples are handled, e.g.
let a = 1,2,3,4,5,6,7,8,9
Tuple<int, int, int, int, int, int, int, Tuple<int, int>>
As a workaround you could do this manually:
let (|G|H|) =
| Choice1Of2() -> G
| Choice2Of2() -> H
// these are not really needed, you could inline them in the active pattern definition below
let G = Choice1Of2()
let H = Choice2Of2()
let (|A|B|C|D|E|F|G_or_H|) =
| 0 -> A
| 1 -> G_or_H G
| 2 -> G_or_H H
| _ -> B
let f a =
match a with
| A -> printfn "A"
| G_or_H G -> printfn "G"
| G_or_H H -> printfn "H"
| _ -> printfn "blah"