Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ambiguity in pattern matching syntax

Tags:

f#

I came across an oddity in the F# pattern matching syntax today, which can lead to apparent failures in the exhaustivity check.

type Thing =
    | This
    | That
    | Other

let useThing =
    function
    | This -> "A"
    | That -> "A"
    | That -> "B" // compiler complains
    | Other -> "B"

In the above scenario the compiler helpfully tells me that the second That rule will never be matched. However, if I had tried to make the code a bit more compact and had written

let useThing =
    function
    | This | That -> "A"
    | That | Other -> "B"    

I do not get any help from the compiler. I think the reason is that | This | That ->. "A" is not a shortcut for | This -> "A" | That -> "A", even though it looks very much like it is (and I've seen many code samples that treat it as such). Instead, from what I can find, the pipe symbol is used both to separate individual patterns, and also as OR pattern.

This is not a big issue for most DUs, but I encountered the problem when mapping a DU with a large number of cases into another DU with a small number of cases. My attempt to use the shortcut syntax caused a bug.

So my questions are:

  1. Is my interpretation correct?
  2. Is there any workaround apart from listing each pattern on a separate line?
like image 959
Akash Avatar asked Jun 22 '16 15:06

Akash


People also ask

What is pattern matching give an example?

For example, x* matches any number of x characters, [0-9]* matches any number of digits, and . * matches any number of anything. A regular expression pattern match succeeds if the pattern matches anywhere in the value being tested.

How pattern matching is used in scripting language?

Regular programming languages make use of regular expressions (regex) for pattern matching. Pattern matching is used to determine whether source files of high-level languages are syntactically correct. It is also used to find and replace a matching pattern in a text or code with another text/code.

What are pattern matching characters?

Regular expression pattern-matching can be performed with either a single character or a pattern of one or more characters in parentheses, called a character pattern. Metacharacters have special meanings, as described in the following table.


1 Answers

Your interpretation is correct.

By leaving out the actions for the first This and second That you are creating an OR pattern as described in Pattern Matching (F#)

To me this is slightly confusing, too, since the logical 'or' is || in F#. And while it is easy to see the first bar as new alternative and second bar as or in your formatting it becomes less obvious in

let useThing =
    function
    | This
    | That -> "A"
    | That
    | Other -> "B"

However the compiler can tell whether a whole pattern is useless but it cannot simplify a pattern. That | Other has a valid match and is therefore not redundant as considered by the compiler.
You can think of much more involved patterns where it would be not at all clear if parts can be left out or how to simplify them.

like image 82
Friedrich Gretz Avatar answered Oct 05 '22 11:10

Friedrich Gretz