I'm getting a type mismatch compiler error that I do not understand... Sorry for the non-minimal example but I don't know how to minimize it. With the following code
doesNotCompile: RawStr -> Parser RawStr
doesNotCompile = \rawStr ->
chompString rawStr
|> mapChompedRawStr (\s, _ -> s)
I get the compiler error (and others of the same kind)
This 1st argument to mapChompedRawStr has an unexpected type:
236│ chompString rawStr
^^^^^^^^^^^^^^^^^^
This chompString call produces:
Parser {}
But mapChompedRawStr needs its 1st argument to be:
Parser a
Tip: The type annotation uses the type variable a to say that this
definition can produce any type of value. But in the body I see that
it will only produce a record value of a single specific type. Maybe
change the type annotation to be more specific? Maybe change the code
to be more general?
But should not a
resolve to {}
? Or am I missunderstanding something?
If someone wants to try it out, you can clone roc-parser and uncomment doesNotCompile
at the end of file package/Parser/Utf8.roc
. Then
roc check package/Parser/Utf8.roc
.
:thinking: definitely looks like a type checker bug to me
yeah, if you delete the implementation of mapChompedRawStr
(so only the mapChompedRawStr :
type annotation remains), it type-checks
so that means the bug has to do with how the type annotation and the implementation get unified
Interesting
@Ayaz Hafiz is on vacation right now, but he's an absolute master at zapping type checker bugs, so he'd be the best person to look into this once he gets back :big_smile:
Great then I will wait for his expertise :grinning_face_with_smiling_eyes:
Okay, so this is due to some changes we recently made with regard to how (and when) functions can be generalized. In short, the premise is that
f = \x -> x # f : a -> a for any `a`
g = f # g : w1 -> w1 for exactly *one* `w1`, not any `w1`
g1 = \x -> f x # g1 : b -> b for any `b` again
If you update your definition of mapChompedRawStr
to
mapChompedRawStr : Parser a, (RawStr, a -> b) -> Parser b
mapChompedRawStr = \parser, mapper ->
Parser.Advanced.Utf8.mapChompedRawStr parser mapper
things will work as you expect.
I have a plan for how to improve error messages in this case, but it hasn't been implemented yet. If you're interested in why things are this way, check out #ideas > Let-generalization - let's not?
Thanks!
Last updated: Jul 05 2025 at 12:14 UTC