0

I'm eagerly trying to learn functional programming in js, but I am having a hard time. I feel like I am constantly doing stuff like this, which just doesn't feel right at all:

export const getParamFromUrl = R.curry((name, url) => R.compose(
    R.match(new RegExp(`[?&]${name}=([^&]*)`))
)(url));

I don't feel like I should be invoking compose immidiately. So what's the correct way to do function composition with an arity of say two?

EDIT: For clarity this is the actual function as it looks (and I know this it isn't the best way to get query strings)

/* util.toMaybe takes a function and a value and returns Nothing()
   if the function returns true and Just(value) if it returns false.
   I think this is the HM:
   util.toMaybe :: (a -> Boolean) -> a -> Maybe a
*/
export const getParamFromUrl = R.curry((name, url) => R.compose(
    R.chain(util.toMaybe(R.isEmpty)),
    R.map(R.nth(1)),
    util.toMaybe(R.isEmpty),
    R.match(new RegExp(`[?&]${name}=([^&]*)`))
)(url));

With the accepted answer this would the become:

export const getParamFromUrl = R.curry(R.compose(
    R.chain(util.toMaybe(R.isEmpty)),
    R.map(R.nth(1)),
    util.toMaybe(R.isEmpty),
    (name, url) => R.match(new RegExp(`[?&]${name}=([^&]*)`), url)
));
Jacob Lauritzen
  • 2,690
  • 1
  • 18
  • 17
  • Maybe I'm not getting the functional side of things. Do you need to curry right away? What's wrong with a regular function like `(name, url) => url.match(new RegExp())[1]` You can always wrap/curry that function later, right? – fet Nov 30 '16 at 01:09
  • That's also a terribly unreliable way to parse URL parameters – Mulan Nov 30 '16 at 05:17

1 Answers1

1

It's not really clear what you mean to do with that compose call. The function will work equally well without it, and it's more clear.

const getParamFromUrl = R.curry((name, url) => 
    R.match(new RegExp(`[?&]${name}=([^&]*)`), url));

If you plan on adding another function into the composition then you can do it like this:

const getParamFromUrl = R.curry(R.compose(
    nth(1),
    (name, url) => R.match(new RegExp(`[?&]${name}=([^&]*)`), url)
));

Note that for technical reasons, the result of compose is not auto-curried, so you need to do that yourself.

You can see this in action on the Ramda REPL.

Scott Sauyet
  • 49,207
  • 4
  • 49
  • 103
  • Thank you so much, composing the higher-arity function makes so much sense. I feel like this idea is exactly what I was looking for but just could not work out myself. I have edited my question to try and shed some light on why I used composition in the first place. – Jacob Lauritzen Nov 30 '16 at 09:12