Stream: beginners

Topic: Pattern matching on list - says not exhaustive when it is


view this post on Zulip Ian McLerran (Jun 10 2024 at 19:40):

I'm attempting to pattern match on a pair of lists. I believe that I have covered all possible permutations, but the compiler says I have not. Here is my code:

when (left, right) is
        ([], _) ->  #1
        (_, []) ->  #2
        ([l], [r]) ->  #3
        ([l], [r, .. as rs]) -> #4
        ([l, .. as ls], [r]) -> #5
        ([l, .. as ls], [r, .. as rs]) -> #6

So, since I have a pair of lists, each list may be 0,1..N elements. So the permutations are:

0,0 : covered by #1
0,1 : covered by #1
0,N : covered by #1
1,0 : covered by #2
1,1 : covered by #3
1,N : covered by #4
N,0 : covered by #2
N,1 : covered by #5
N,N : covered by #6

Yet compiler says:

This when does not cover all the possibilities:
...
Other possibilities include:
    ( [_, ..], _ )

The case described by the compiler would be covered by # 2, 5, and 6. - [(N,0), (N,1), (N,N)], which is exhaustive for the cases described in the error.

view this post on Zulip Norbert Hajagos (Jun 10 2024 at 20:02):

I can't help more, but to say yes, this seem exhaustive.

view this post on Zulip Ian McLerran (Jun 10 2024 at 20:07):

I threw a (_, _) -> crash "..." on my code, and it compiles, but that makes me pretty squeamish.. :rolling_eyes:

view this post on Zulip timotree (Jun 10 2024 at 20:21):

Maybe exhaustiveness checking struggles with overlapping patterns? Right now the patterns are not disjoint since [42] would be matched by both [x] and [x, .. as xs] (with xs = []). What happens if you change the length=N cases to use a pattern that matches on the first two elements?

view this post on Zulip Brendan Hansknecht (Jun 10 2024 at 20:32):

Yeah, I think bug

view this post on Zulip Ian McLerran (Jun 11 2024 at 01:19):

As far as the [x] overlapping with [x, ..] goes, I need to differentiate between [x] and [x, ..]. Originally, I didn't have cases 2, 3, or 4. They were only added because the compiler was the same error message and I though, oh, maybe Roc doesn't match .. on empty lists...

I can try throwing in an extra var in the N cases, but since originally I didn't have the 1 cases, I don't expect a change.

view this post on Zulip Ian McLerran (Jun 11 2024 at 02:01):

I'll try to find a min repro for this tomorrow. My guess would be its struggling to determine exhaustiveness on a tuple of lists.

view this post on Zulip Brendan Hansknecht (Jun 11 2024 at 02:10):

Yeah, that makes sense. Not sure what we did for exhaustiveness of records and if it is fully implemented. A tuple is just a weird record

view this post on Zulip Ian McLerran (Jun 11 2024 at 02:24):

Right.. makes sense. Just a record with place-value identifiers instead of names. Hmm... be interesting to see if I can break things with records too.

view this post on Zulip Ian McLerran (Jun 11 2024 at 02:26):

Thats a good point too... assuming records don't break in this way, that would be a much better work around than the (_, _) -> crash I threw on the end of my when block.

view this post on Zulip Ian McLerran (Jun 11 2024 at 02:32):

Actually... do records have any kind of equivalent pattern matching? I can't even imagine what that syntax would look like...

when { left, right } is
    #... ?

view this post on Zulip Brendan Hansknecht (Jun 11 2024 at 02:39):

when {x : 1} is
   {x: 2} -> "2"
   {x: 1} -> "1"
   {x: _} -> "eh"
 ```

view this post on Zulip Ian McLerran (Jun 11 2024 at 02:39):

Ahhh, of course! :sweat_smile:

view this post on Zulip Ian McLerran (Jun 11 2024 at 13:46):

Okay, I can confirm that records are subject to the exact same exhaustiveness checking bug, plus one more:

In the following example the compiler says that the second pattern is redundant, when it is obviously not.

when { lhs: left, rhs: right } is
        { lhs: [] } -> right
        { rhs: [] } -> left
        # ...

view this post on Zulip Anton (Jun 11 2024 at 14:17):

Can you make an issue for that @Ian McLerran?

view this post on Zulip Ian McLerran (Jun 11 2024 at 14:55):

Yep, sure can!

view this post on Zulip Ian McLerran (Jun 11 2024 at 16:14):

Okay, issue filed here.

view this post on Zulip Anton (Jun 11 2024 at 16:15):

Thanks :)


Last updated: Jul 06 2025 at 12:14 UTC