Last active
August 29, 2015 14:05
-
-
Save gilbert/b131bcd0f72f87110582 to your computer and use it in GitHub Desktop.
[Practical] Partial Application in Ruby
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'deterministic' | |
class X | |
include Deterministic | |
def go | |
# The `>>` is from Deterministic. It feeds the result | |
# of the left side into the right side. | |
# get_num >> mcurry(:add, 1) >> mcurry(:double) | |
get_num >> _add(1) >> _double | |
end | |
def get_num | |
Success(11) | |
end | |
def add(x,y) | |
Success(x + y) | |
end | |
def double(x) | |
Success(x * 2) | |
end | |
# A helper to curry an existing instance method | |
def mcurry(method_name, *args) | |
m = method(method_name).to_proc | |
if args.length - m.arity > 1 | |
raise ArgumentError.new("too many curried arguments for #{method_name} (#{args.length} for #{m.arity}; you need to leave exactly one open)") | |
elsif args.length - m.arity == 0 | |
lambda { m[*args] } | |
else | |
m.curry[*args] | |
end | |
end | |
# By prepending a method call with _, we can automatically generate | |
# a curried lamda version of that intsance method! | |
def method_missing(meth, *args, &block) | |
name = meth.to_s | |
real_method = name[1..-1] | |
if name[0] == '_' && self.respond_to?(real_method) | |
mcurry(real_method, *args, &block) | |
else | |
super | |
end | |
end | |
end | |
x = X.new | |
puts "RESULT: #{x.go.inspect}" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment