Haskell-style partial application and composition for Ruby methods
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.
spec Introduced >= (pipeline) operator Jul 13, 2013
.gitignore initial commit Jul 10, 2013
README.md Use Ruby 2.0 decorator syntax May 17, 2015



Haskell-style partial application and composition for Ruby methods

Function composition when used in conjunction with partial application can yield exceptionally concise code, often more concise than the idiomatic Ruby. Check out the links below for further explanations of these features and examples of their use in Haskell:

Partial application in Haskell
Function composition in Haskell
Currying in Haskell

Also, watch this video to learn about some of the cool things you can do with function composition and partial application (the video is in Javascript but the ideas still apply to Ruby with Funkify)



In order for a Ruby method to be amenable to partial application and composition it must first be autocurried:

class MyFunkyClass
  include Funkify

  # we make a specific method autocurried using the auto_curry method (Here with Ruby 2.0 decorator syntax)
  auto_curry def add(x, y)
    x + y

  # alternatively, if we invoke auto_curry without a parameter
  # then all subsequent methods will be autocurried

  def mult(x, y)
    x * y

  def negate(x)

Partial application and currying

When a method supports autocurrying it can still be invoked normally (if all parameters are provided) however if less than the required number are given a Proc is returned with the given parameters partially applied:

funky = MyFunkyClass.new

funky.add(1, 2) #=> This works normally and returns 3
add_1 = funky.add(1) #=> The `1` is partially applied and a `Proc` is returned
add_1.(2) #=> 3 (We invoke that `Proc` with the remaining argument)

Function composition

We compose methods using the * and | operators.

* composes right to left, this is the standard way to compose functions found in languages like Haskell:

(mult(5) * add(1)).(10) #=> 55

# We can further compose the above with another method:
(negate * mult(5) * add(1)).(10) #=> -55

| composes left to right, like a shell pipeline:

(mult(5) | add(1) | negate).(3) #=> -16

As a cute bonus, we can inject values from the left into a pipeline with the pass method together with the >= (pipeline operator) (see more):

pass(3) >= mult(5) | add(1) | negate #=> -16

Other examples:

Add 10 to every item in an Enumerable:

(1..5).map &funky.add(10) #=> [11, 12, 13, 14, 15]

Multiply by 10 and negate every item in an Enumerable:

(1..5).map &(funky.negate * funky.mult(10)) #=> [-10, -20, -30, -40, -50]


Add this line to your application's Gemfile:

gem 'funkify'

And then execute:

$ bundle

Or install it yourself as:

$ gem install funkify


This library was inspired in part by stimulating conversations with epitron on Freenode.


  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request