rescript-compiler
rescript-compiler copied to clipboard
Compiler bug in applying an uncurried function when the function has a signature
This causes a compile error that the interface doesn't match the signature even though the types are exactly the same in the error. Without the signature it compiles just fine.
Some pointers:
- Adding the type annotation to the function in the implementation suddenly makes it compile
- Wrapping the function also fixes the issue
- Using core's Array function also makes it compile
So it seems to be a bug in using externals in uncurried mode because the issue is not present when the map function is not an external
You can even simplify it down to this:
module Bla: {
let array: ('a => 'b, Js.Array.t<'a>) => Js.Array.t<'b>
} = {
let array = (encoder, arr) => Js.Array.map(encoder, arr)
}
I think the issue comes from the fact that Js.Array.map is curried and expects its mapper function to be curried, the error message is right, it should just mention the difference in the curried state of the function between expected and actual. Basically some cases (especially when the faulty function is a parameter of a function) is not fixed by #6414. Given we're sunsetting Js lib in v12, I'm not sure we have to do anything here.
The right error message should be like this:
Signature mismatch:
...
Values do not match:
let array: ('a => 'b (curried), Js.Array.t<'a>) => Js.Array.t<'b>
is not included in
let array: ('a => 'b (uncurried), Js.Array.t<'a>) => Js.Array.t<'b>
playground.res:2:3-57: Expected declaration
playground.res:4:7-11: Actual declaration
I am trying to wrap my brain around this, but if we have a function with one argument what is the difference between curried and uncurried. Is it that the function is potentially partially applied?
And I thought the stdlib would be all uncurried with the uncurried setting turned on. How would I know what is curried vs uncurried? Isn't the switch just compiling everything as uncurried? I think it's strange that there is a possibility of anything being curried when the flag is turned on - I think it's way more consistent that this is a system-wide thing.
About deprecating Js. Will that remove the possibility of directly using functions in the Js stdlib, or is / will that be included in Core?
A unary curried function that returns a unary curried function is what's called a binary curried function. With uncurried, a binary function is another thing. So curried and uncurried are always different things, whatever the arity.
A unary curried function that returns a unary curried function is what's called a binary curried function. With uncurried, a binary function is another thing. So curried and uncurried are always different things, whatever the arity.
Understood. I didn't know that the stdlib is still curried in uncurried mode, perhaps we can do something to make this clear? I think it's pretty weird to be honest, why would you want this to be curried?
But at least it would be great to fix the error so that it's clear that the difference is that one function is curried and the other is not. That would make me track down this bug way easier :)
This becomes non-existent in V12. OK to close?