roc
roc copied to clipboard
Improve type mismatch error: this need to be `a` but it is `a`
interface Foo
exposes [validFn]
imports []
invalidFn : {} -> *
invalidFn = \_ -> validFn {} (\_ -> Foo)
validFn : a, (a -> [Foo]) -> a
validFn = \s, toMaybe ->
h : a -> a
h = \x ->
when toMaybe x is
Foo -> invalidFn {}
h s
Type mismatch in question:
── TYPE MISMATCH in package/Rocon.roc ──────────────────────────────────────────
This 1st argument to toMaybe has an unexpected type:
12│ when toMaybe x is
^
This x value is a:
a
But toMaybe needs its 1st argument to be:
a
────────────────────────────────────────────────────────────────────────────────
It's easy to see how this mismatch can confuse users :smile:
Full output:
> roc test Foo.roc
── TYPE MISMATCH in package/Rocon.roc ──────────────────────────────────────────
This expression is used in an unexpected way:
6│ invalidFn = \_ -> validFn {} (\_ -> Foo)
^^^^^^^^^^^^^^^^^^^^^^
This validFn call produces:
{}
But you are trying to use it as:
*
Tip: The type annotation uses the type variable * 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?
── TYPE MISMATCH in package/Rocon.roc ──────────────────────────────────────────
This 1st argument to toMaybe has an unexpected type:
12│ when toMaybe x is
^
This x value is a:
a
But toMaybe needs its 1st argument to be:
a
────────────────────────────────────────────────────────────────────────────────
2 errors and 0 warnings found in 28 ms
Due to the multiple type mismatches this example is pretty difficult so if we can get a simpler case to investigate that would be great :)
This might be simpler example:
interface Foo
exposes [bar]
imports []
foo : a, (a -> a) -> a
foo = \x, f -> bar x f
bar : a, (a -> a) -> a
bar = \x, f ->
baz : a
baz = f x
foo x f
It fails with just the single error:
── TYPE MISMATCH in Foo.roc ────────────────────────────────────────────────────
Something is off with the body of the baz definition:
10│ baz : a
11│ baz = f x
^^^
This f call produces:
a
But the type annotation on baz says it should be:
a
────────────────────────────────────────────────────────────────────────────────
1 error and 1 warning found in 26 ms
The error goes away after any of the following changes:
- Remove implementation of
baz - Remove type annotation of
baz - Remove type annotation of
bar - Remove implementation of
foo
Awesome, thanks @jwoudenberg :)
@Anton-4 are you working on a fix for this? I would like to give it a shot.
No, I've now assigned you to this issue :) Thanks for your help @eckertliam!
I don't think either of these should actually be type errors. Unless I'm misunderstanding something I think the programs should compile fine. The issue is that a in the type annotation is not used in the inner annotations' a.
I wonder if we could add a suggestion? maybe it would be possible to detect this somehow and provide a suggestion like "the types are different even though they are have the same name"
Or perhaps there is a way to prevent this kind of issue by making it invalid to use the same type variable in an inner annotation?