Created
November 21, 2014 18:45
-
-
Save jin/4f49662e1587fda22401 to your computer and use it in GitHub Desktop.
Functional Ruby: implementing commonly used functions with lambda objects
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
# Regular Ruby methods, can't pass them around like function objects | |
def length(xs) | |
return 0 if xs.empty? | |
1 + length(xs[1..-1]) | |
end | |
def map(xs, process = -> (x) { x }) | |
return [] if xs.empty? | |
[process.call(xs.first)] + map(xs[1..-1], process) | |
end | |
# Lambda objects | |
length_func = -> (xs) { xs.empty? ? 0 : 1 + length_func.call(xs[1..-1])} | |
map_func = -> (xs, process) do | |
return [] if xs.empty? | |
[process.call(xs.first)] + map_func.call(xs[1..-1], process) | |
end | |
filter_func = -> (xs, filter) do | |
return [] if xs.empty? | |
x = xs.first | |
if filter.call(x) | |
[x] + filter_func.call(xs[1..-1], filter) | |
else | |
filter_func.call(xs[1..-1], filter) | |
end | |
end | |
take_func = -> (xs, num) do | |
return [] if xs.empty? || num.to_i <= 0 | |
[xs.first] + take_func.call(xs[1..-1], num - 1) | |
end | |
# Testing | |
puts length [] # => 0 | |
puts length [1, 2, 3] # => 3 | |
puts length_func.call([]) # => 0 | |
puts length_func.call([1, 2, 3]) # => 3 | |
p map([]) # => [] | |
p map([1, 2]) # => [1, 2] | |
p map([1, 2, 3], Proc.new { |x| x.to_i * x.to_i } ) # => [1, 4, 9] | |
p map([1, 2, "foo"], Proc.new { |x| x.to_i * x.to_i } ) # => [1, 4, 9] | |
p map_func.call([1, 2, 3], Proc.new { |x| x.to_i * x.to_i }) # => [1, 4, 9] | |
p map_func.call([1, 2, "foo"], Proc.new { |x| x.to_i * x.to_i }) # => [1, 4, 0] | |
p filter_func.call([], -> (x) { x } ) # => [] | |
p filter_func.call([1, 2, 3], -> (x) { x.odd? }) # => [1, 3] | |
p take_func.call([], 1) # => [] | |
p take_func.call([1, 2, 3], 0) # => [] | |
p take_func.call([1, 2, 3], 2) # => [1, 2] | |
p take_func.call(map_func.call(filter_func.call((1..3000).to_a, -> (x) { x.odd? } ), -> (x) { x * x }), 42) | |
# => [1, 9, 25, 49, 81, 121, 169, 225, 289, 361, 441, 529, 625, 729, 841, 961, 1089, 1225, 1369, 1521, 1681, 1849, 2025, 2209, 2401, 2601, 2809, 3025, 3249, 3481, 3721, 3969, 4225, 4489, 4761, 5041, 5329, 5625, 5929, 6241, 6561, 6889] | |
# Stack too deep for 10000 elements array | |
# p take_func.call(map_func.call(filter_func.call((1..10000).to_a, -> (x) { x.odd? } ), -> (x) { x * x }), 42) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment