Closed masaeedu closed 5 years ago
@davidchambers I'm not sure if "nasty" functions here are ones that accept multiple arguments (i.e. Function.prototype.length > 1
), as is the case with the input to curry
. If so, the function produced by uncurry
does not qualify, because it still only accepts a single argument.
Regarding heterogeneous arrays, there's already a couple of fairly essential convenience functions that work with heterogeneous arrays (pipe
, pipeK
), without which code quickly turns into a muddle of parentheses and temporary variables. uncurry
is just another function for facilitating working with the library under JS's syntax constraints, although it is admittedly of more niche utility than the other two.
[T]he function produced by
uncurry
[…] still only accepts a single argument.
Thanks for the correction, Asad.
You're right to point out that pipe
and pipeK
accept heterogeneous arrays. I'm reluctant to let this looseness spread. ;)
I have this exact function in my codebases, called apply
, as a utility. I see the points @davidchambers makes and they make sense as an argument for lack of inclusion into sanctuary itself.
@davidchambers I think the reason this sort of thing is seen as "loose" is because of lack of expressiveness in the type system. We can imagine sound types for these functions that would work in dependently languages like Idris (and indeed, JS :wink:):
// :: type Curried [] r = r
// :: Curried [x, ...xs] r = x -> Curried xs r
// :: Curried a r -> a -> r
const uncurry = f => args => args.reduce((p, c) => p(c), f)
// :: type Length [] = 0
// :: Length [x, ...xs] = 1 + Length xs
// :: Length a -> (a -> r) -> Curried a r
const curry = n => f => {
const rec = a => acc => (a === 0 ? f(acc) : x => rec(a - 1)([...acc, x]))
return rec(n)([])
}
A nice utility to have would be a simple
uncurry
function that takes a curried function of an arbitrary number of arguments and an array consisting of a corresponding number of values, and applies the latter to the former. The implementation could be:This would help clean up some parens noise in certain places, and works well with things like the pipeline operator; i.e.
[2, 2] |> uncurry(S.add) // => 4
.