Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Functions: `curry`

Functions: curry

A compilation of my favorite functions and patterns in functional programming

Haskell Curry is a giant. His first name denotes a textbook functional programming language, his last name a technique in functional programming. It's his surname that I shall address here.

While learning to program, currying to me seemed some esoteric concept in FP reserved for practitioners of Haskell and Clojure. But, in practical usage, it's remarkably simple.

As a general rule, any time I find myself calling the same function -- and passing it the same arguments -- it's a good time to curry the function. When a function is curried, we can preload it with certain arguments, and then pass it whatever its remaining arguments at will.

Say our codebase relies heavily on a third-party API method bearing the following signature:

makeApiRequest(requestType = '', url = '', headers = {}, body = {}) → Response

Where requestType is one of GET, POST, or PUT.

It won't take long before we tire of writing makeApiRequest('GET', ...) and makeApiRequest('POST', ...) over and again. Now, we could abstract our own helper functions like so:

export async function post(url = '', headers = {}, body = {}) {
  return makeApiRequest('POST', url, headers, body)
}

export async function put(url, headers = {}, body = {}) {
  return makeApiRequest('PUT', url, headers, body)
}

export async function get(url, headers = {}) {
  return makeApiRequest('GET', url, headers)
}

But I find it a bit tedious to rewrite all the arguments for each function definition. Instead, we could simply curry the function:

import {curry} from 'ramda'

export async function makeCurriedApiRequest() {
  return curry(makeApiRequest)
}

And then leverage our curried variation to preload any desired arguments:

export async function get() {
  return makeCurriedApiRequest('GET')
}

export async function post() {
  return makeCurriedApiRequest('POST')
}

export async function put() {
  return makeCurriedApiRequest('PUT')
}

Though not impossible to write your own curry function, I would advise use of Lodash/FP or Ramda, as their variations are more flexible and more powerful.

Resources

Further reading

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment