evilsoft / crocks

A collection of well known Algebraic Data Types for your utter enjoyment.
https://crocks.dev
ISC License
1.59k stars 102 forks source link

README.md example confusion with `curry` #454

Closed sunwukonga closed 4 years ago

sunwukonga commented 4 years ago

Is your feature request related to a problem? Please describe. Based on my understanding of what curry should do, I would expect it to behave like this:

const uncurriedAdd = (x, y) = x + y
const curriedAdd = curry( add )
console.log(curriedAdd(20, 4))
// [Function]

Just as it would if I did:

const properlyCurriedAdd = x => y => x + y
console.log(properlyCurriedAdd(20, 4))
// [Function]

Describe the solution you'd like This is very convenient behavior. I'm only requesting to change the README.md to explicitly use the curry'd form first and then explain the convenience. i.e.

safeDivide(20)(0)
//=> Nothing

// for convenience, the function returned by curry() can also be called with
safeDivide(20, 0)
//=> Nothing
evilsoft commented 4 years ago

I like this idea! It can be 🌽fusing, especially if a person is new to doing Functional Programming with JS. I do not see that this could hurt at all. We could probably also make an example for the docs as well that includes this information: https://crocks.dev/docs/functions/helpers.html#curry

If you want to contribute, please feel free to submit a PR for review, otherwise we can make sure to get the README and docs updated to make it a bit more clear.

sunwukonga commented 4 years ago

Yes, of course. I asked because I'd like to contribute.

sunwukonga commented 4 years ago

I'm working some examples for the curry docs, and I'm having trouble with the type signature of curriedAdd.

// add :: (Number, Number, Number) => Number
const add = (x, y, z) =>
  x + y + z

// curriedAdd :: (Number, Number, Number) -> Number
// curriedAdd :: (Number, Number) -> Number -> Number
// curriedAdd :: Number -> (Number, Number) -> Number
// curriedAdd :: Number -> Number -> Number -> Number
const curriedAdd = curry( add )

Haskell would not be happy with the redefinition, but beyond that, it would also be unhappy with the change in the number of clauses. I think it's impossible to write the definition of this function in Haskell notation.

sunwukonga commented 4 years ago

A four argument curry would have eight type signatures. Five arguments, sixteen. So on and so forth. Generally, there are 2^(n-1) type signatures, where n is the number of arguments in the function to be curried.

dalefrancis88 commented 4 years ago

So the policy we've tended to adopt throughout the frameworks docs is to favour the unary type signature, // curriedAdd :: Number -> Number -> Number -> Number It's then generally understood that you can have the added benefit or calling a curried function with n parameters and all parameters are applied to the underlying curried function. I think if you kept the example simple, as you have, you can then show that a curried function can be invoked with n arguments. It might also be nice to show the behaviour for optional parameters here as well maybe?

sunwukonga commented 4 years ago

"It might also be nice to show the behaviour for optional parameters here as well maybe?"

Yes, will do. That's a nasty gotcha if you don't see it coming.

dalefrancis88 commented 4 years ago

Yeah it catches me out so many times,

dalefrancis88 commented 4 years ago

@sunwukonga would you count this issue as closed?