Stream: beginners

Topic: Pattern matching seems not exclude a handles case


view this post on Zulip Ilya Shmygol (Apr 16 2025 at 12:42):

Another example of questionable behaviour in my opinion.
Here is a piece of code i had:

parse_template_recursive : List U8, List (Spec _) -> Result (List (Spec _)) [InvalidTemplate([MissingClosingBracket])]
parse_template_recursive = |template_codes, acc|
    when split_first_segment(template_codes) is
        Err(ListWasEmpty) -> Ok(acc)
        Err(MissingClosingBracket) -> MissingClosingBracket |> InvalidTemplate |> Err
        Ok({before : ['{', .. ,'}'], others}) -> crash("Not implemented yet")
        Ok({before, others}) -> crash("Not implemented yet")

split_first_segment may currently return only 2 types of errors: ListWasEmpty and MissingClosingBracket, but in the feature may be extended with other errors. Should the pattern matcher be smart enough to understand this:

parse_template_recursive : List U8, List (Spec _) -> Result (List (Spec _)) [InvalidTemplate([MissingClosingBracket])]
parse_template_recursive = |template_codes, acc|
    when split_first_segment(template_codes) is
        Err(ListWasEmpty) -> Ok(acc)
        Err(reason) -> reason |> InvalidTemplate |> Err
        Ok({before : ['{', .. ,'}'], others}) -> crash("Not implemented yet")
        Ok({before, others}) -> crash("Not implemented yet")

Because currently even if I do handle a case when ListWasEmpty has being thrown I still get an error:

TYPE MISMATCH
Something is off with the body of the
`parse_template_recursive` definition:
120│   parse_template_recursive : List U8, List (Spec _) -> Result (List (Spec _)) [InvalidTemplate([MissingClosingBracket])]
121│   parse_template_recursive = |template_codes, acc|
122│>      when split_first_segment(template_codes) is
123│>          Err(ListWasEmpty) -> Ok(acc)
124│>          Err(reason) -> reason |> InvalidTemplate |> Err
125│>          Ok({before : ['{', .. ,'}'], others}) -> crash("Not implemented yet")
126│>          Ok({before, others}) -> crash("Not implemented yet")
This `when` expression produces:
    [
        Err [InvalidTemplate [
            ListWasEmpty,
            MissingClosingBracket,
        ]],
        Ok (List (Match.Spec c)),
    ]
But the type annotation on
`parse_template_recursive` says it should be:
    Result (List (Match.Spec c)) [InvalidTemplate [MissingClosingBracket]]

view this post on Zulip Anton (Apr 16 2025 at 13:14):

Should the pattern matcher be smart enough to understand this

Yes, it should be but it is quite limited at the moment. I'll make an issue.

view this post on Zulip Anton (Apr 16 2025 at 16:51):

#7748

view this post on Zulip Brendan Hansknecht (Apr 16 2025 at 17:17):

No this should not work

view this post on Zulip Brendan Hansknecht (Apr 16 2025 at 17:17):

As much as it feels it should

view this post on Zulip Brendan Hansknecht (Apr 16 2025 at 17:17):

Roc has no gradual typing

view this post on Zulip Brendan Hansknecht (Apr 16 2025 at 17:18):

The type of reason is [ListWasEmpty, MissingClosingBracket]

view this post on Zulip Brendan Hansknecht (Apr 16 2025 at 17:19):

Think of it like this. If you had an enum Color: [Red, Green, Blue]. Even if the function is guaranteed to return Blue, the type is still Color. The same thing is happening here

view this post on Zulip Brendan Hansknecht (Apr 16 2025 at 17:20):

I know this has been discussed in the past, but I don't think there are any current plans to add gradual typing for tag unions.

view this post on Zulip Anton (Apr 16 2025 at 17:46):

No this should not work

Yeah, I was doubting as well when I wrote up the issue. I'll close it.

view this post on Zulip Ilya Shmygol (Apr 16 2025 at 19:39):

Got it, thanks.


Last updated: Jul 06 2025 at 12:14 UTC