Stream: beginners

Topic: ✔ Can't make heads or tails of the type inference here...


view this post on Zulip Ian McLerran (Jan 31 2025 at 20:31):

I have the following:

Parser a err: Str -> Result (a, Str) err

flat_map : (Parser a _), (a -> Parser b _) -> Parser b _
flat_map = |parser_a, a_to_parser_b|
    |str|
        when parser_a(str) is
            _ -> crash "TODO"
            # Ok(a, rest) ->
            #     a_to_parser_b(a)(str)
            # Err err -> Err err

My commented out code here was not checking, so I put in a _ to view the language servers type inference. According to type inference, when parser_a(str) is produces: Result ( b, Str )* *, as shown in the screenshot. This makes no sense to me, since parser_a's type is Str -> Result (a, Str) _.

Screenshot 2025-01-31 at 14.26.43.png

Am I just low on coffee, or is there something weird going on with the type inference here?

view this post on Zulip Luke Boswell (Jan 31 2025 at 20:35):

You've applied the str to it though, so isn't this the type after calling the function, which is a Result?

view this post on Zulip Ian McLerran (Jan 31 2025 at 20:37):

Yeah, but I'd expect a Result (a, Str) *, not a Result (b, Str)* *...

view this post on Zulip Luke Boswell (Jan 31 2025 at 20:38):

Ohk, it's the b not a type var you're concerned about.

view this post on Zulip Luke Boswell (Jan 31 2025 at 20:38):

Could it be getting that from the return value? -- and because you're only calling parser_a, it unifies those two type vars as the same thing... but prints out b because it saw that first ... or something like that?

view this post on Zulip Ian McLerran (Jan 31 2025 at 20:48):

Well if I uncomment the commented out code, thus using a_to_parser_b it still doesn't unify the types, so not sure if thats it...

view this post on Zulip Ian McLerran (Jan 31 2025 at 20:49):

flat_map : (Parser a _), (a -> Parser b _) -> Parser b _
flat_map = |parser_a, a_to_parser_b|
    |str|
        when parser_a(str) is
            Ok(a, _rest) ->
                a_to_parser_b(a)(str)
            Err err -> Err err

==

This 1st argument to a_to_parser_b has an unexpected type:

20│                  a_to_parser_b(a)(str)
                                   ^

This a value is a:

    (
        a,
        Str,
    )b

But a_to_parser_b needs its 1st argument to be:

    a

I don't understand how the a in Ok(a, _rest) can be (a, Str)b!

view this post on Zulip Ian McLerran (Jan 31 2025 at 20:51):

I feel like I must be misapplying my functions, but darned if I can figure it out... I think my brain just went caput for the day :sweat_smile:

view this post on Zulip Ian McLerran (Jan 31 2025 at 21:53):

Just needed to take a break! My when block needed nested parens.

when parser_a(str) is
    Ok((a, _rest)) ->
        #...

view this post on Zulip Notification Bot (Jan 31 2025 at 21:53):

Ian McLerran has marked this topic as resolved.


Last updated: Jul 06 2025 at 12:14 UTC