Skip to content

Extend parameterized partial and single-case active patterns to _complete, multi-case_ active patterns #1213

Open
@abelbraaksma

Description

@abelbraaksma

This question came up a few times recently on Slack, which suggests to me there's a real-world use case for this scenario. This active SO question is another cry for this feature.

I propose we extend support of parameterized active patterns to include total active patterns, where the pattern has multiple choices.

There's currently no existing way of doing this in F#, such patterns are explicitly forbidden.

Example

let (|Ge|Lt|) x y =
   if y >= x then Ge
   else Lt

let f() = 
    match 42 with 
    | Ge 12 -> "greater or equal"
    | Lt 12 -> "smaller"

Syntax

As the above example shows, one might think that writing Lt 11 would make the pattern match non-total. This is correct, and honestly I don't have a good way around it. Since a total active pattern is considered a single block, perhaps the rule could be that only the first item should have the argument. After all, that's how such patterns are compiled currently:

Improved example

let (|Ge|Lt|) x y =
   if y >= x then Ge
   else Lt

let f() = 
    match 42 with 
    | Ge 12 -> "greater or equal"
    | Lt -> "smaller"

Pros and Cons

The advantages of making this adjustment to F# are

  • orthogonality between the different types of active patterns\
  • allows writing parameterized total active patterns

The disadvantages of making this adjustment to F# are

  • it's work
  • some may consider the "totality check" to become ambiguous, see above for a solution.

Extra information

Estimated cost (XS, S, M, L, XL, XXL): S

Related suggestions: I couldn't find any, though I'd be surprised if this wasn't suggested before.

Affidavit (please submit!)

Please tick this by placing a cross in the box:

  • This is not a question (e.g. like one you might ask on stackoverflow) and I have searched stackoverflow for discussions of this issue
  • I have searched both open and closed suggestions on this site and believe this is not a duplicate
  • This is not something which has obviously "already been decided" in previous versions of F#. If you're questioning a fundamental design decision that has obviously already been taken (e.g. "Make F# untyped") then please don't submit it.

Please tick all that apply:

  • This is not a breaking change to the F# language design
  • I or my company would be willing to help implement and/or test this

For Readers

If you would like to see this issue implemented, please click the 👍 emoji on this issue. These counts are used to generally order the suggestions by engagement.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions