I’ve been struggling to acclimate myself to the new uncurried system. One of the things that puzzles me is what the difference is between curried and uncurried when there’s a single argument. For example, we extensively use @deriving(jsConverter)
to make string-like enum types, and we have a helper function to turn those into decoders that will work with decco
:
let makeStringLikeDecode = (name, fromJs, json) =>
json
->Decco.stringFromJson
->Belt.Result.flatMap(s =>
s->fromJs->ResultUtils.fromOption(makeDeccoError(`Invalid string value for ${name}`, json))
)
And then it’s called like
@deriving(jsConverter)
type t = [ #First | #Second | #Third ];
let t_encode = t => t->tToJs->Js.Json.string
let t_decode = JsonUtils.makeStringLikeDecode("MyModule.t", tFromJs)
Because everything is uncurried now, I had to change the definition of makeStringLikeDecode
to explicitly curry the first two arguments from the last:
let makeStringLikeDecode = (name, fromJs) => json =>
json
->Decco.stringFromJson
->Belt.Result.flatMap(s =>
s->fromJs->ResultUtils.fromOption(makeDeccoError(`Invalid string value for ${name}`, json))
)
However, I’m still getting a compiler error now:
FAILED: src/MyModule-MyProject.cmj
We've found a bug for you!
/project/src/MyModule.res:5:63-69
3 │
4 │ let t_encode = m => m->tToJs->Js.Json.string
5 │ let t_decode = JsonUtils.makeStringLikeDecode("MyModule.t", tFromJs)
6 │
7 │
This function is a curried function where an uncurried function is expected
Can’t see it in the snippet above but the tFromJs
is highlighted red here. This is strange because tFromJs
only takes a single argument, so it would seem that there’s no difference whether or not it’s curried. Furthermore I’m not aware of anything I can do at the code level to change it. Inside of makeStringLikeDecode
there’s just a function call to fromJs
with one argument. I tried changing s->fromJs
to fromJs(. s)
but that had no effect (I’d seen discussed that the dot syntax might be used to indicate a curried function call, but it would appear that’s not a thing now). So, how can I tell the compiler that fromJs
is supposed to be (or is allowed to be) uncurried?
Beyond that, I don’t think @deriving(jsConverter)
should be emitting curried functions in the first place, if the compiler is in uncurried mode. If there does need to be for some reason a distinction in the compiler between curried and uncurried for single-argument functions, it would seem that the auto-generated functions should be uncurried.
Workaround:
In the process of writing this post I discovered a workaround, which is to change the call site:
let t_decode = JsonUtils.makeStringLikeDecode("MyModule.t", js => tFromJs(js))
This I suppose will unblock me moving forward, but it’s quite cumbersome and redundant to add in the extra lambda function there. And having to go around updating several dozen places in our code base with this change is less than ideal. It should be possible to fix within the function itself so it “just works” rather than needing to update a bunch of call sites.