Skip to content

Instantly share code, notes, and snippets.

@moserrya
Last active December 30, 2015 08:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save moserrya/7800699 to your computer and use it in GitHub Desktop.
Save moserrya/7800699 to your computer and use it in GitHub Desktop.
juxt = ->(*fns) do
->(*args) do
fns.map do |fn|
args.reduce {|acc, e| fn.to_proc.call acc, e}
end
end
end
max = ->(a, b) {a > b ? a : b}
min = ->(a, b) {a < b ? a : b}
juxt.(:+, max, min).(2, 3, 5, 1, 6, 4)
# => [21, 6, 1]
filter = ->(fn, list) {list.find_all {|e| fn.to_proc.call e}}
remove = ->(fn, list) {list.find_all {|e| !fn.to_proc.call e}}
# partition things, strangely
juxt.(filter, remove).(:even?, [1, 2, 3, 4, 5, 6])
# => [[2, 4, 6], [1, 3, 5]]
# works, but we need to rewrite everything in terms of reduce. kind of a bummer. let's try to take advantage of Enumerable and Array!
juxt2 = ->(*fns) do
->(*args) do
fns.map do |fn, *options|
args.send fn, *options
end
end
end
# less work...
juxt2.([:reduce, :+], :max, :min).(1, 2, 3, 4, 5, 6)
# but how do we pull off our fun filtering trick? one possibility:
juxt3 = ->(*fns) do
->(*args) do
fns.map do |fn, *options|
options.empty? ? args.send(fn) : eval("#{args}.#{fn}(&:#{options.first})")
end
end
end
juxt3.([:find_all, :even?], [:find_all, :odd?]).(1, 2, 3, 4, 5, 6)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment