ruby 35 lines · 7 steps

Currying lambdas and methods in Ruby

Ruby's Proc#curry turns a multi-argument callable into one that accepts its arguments one at a time.

Explained by highlit
1# Curry a multi-argument lambda so it can be applied one argument at a time.
2add = ->(a, b, c) { a + b + c }
3 
4# Proc#curry returns a curried version that collects arguments incrementally.
5curried_add = add.curry
6 
7step1 = curried_add[1] # => #<Proc> still waiting for two more args
8step2 = step1[2] # => #<Proc> waiting for one more arg
9result = step2[3] # => 6, fully applied
10 
11# You can also supply several arguments at once.
12curried_add[1][2, 3] # => 6
13curried_add[1, 2, 3] # => 6
14 
15# Methods become curryable by first converting them to a Proc.
16class Discounter
17 def apply(rate, base_price)
18 base_price - (base_price * rate)
19 end
20end
21 
22discounter = Discounter.new
23discount = discounter.method(:apply).to_proc.curry
24 
25# Build specialized functions by partially applying the first argument.
26ten_percent_off = discount[0.10]
27half_off = discount[0.50]
28 
29ten_percent_off[100] # => 90.0
30half_off[100] # => 50.0
31 
32# curry(arity) lets you fix how many arguments to expect for variadic procs.
33join = ->(*parts) { parts.join('/') }
34path = join.curry(3)
35full = path['usr']['local']['bin'] # => "usr/local/bin"
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Currying lets you fix some arguments now and supply the rest later, building specialized functions from general ones.
  2. 2A curried proc returns either another proc (when under-applied) or the final result (when fully applied), so you can chain calls flexibly.
  3. 3Methods aren't procs, but method(:name).to_proc bridges the gap so any method can be curried too.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Currying lambdas and methods in Ruby — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code