Skip to content

Instantly share code, notes, and snippets.

@luikore
Last active September 24, 2015 10:57
Show Gist options
  • Save luikore/737238 to your computer and use it in GitHub Desktop.
Save luikore/737238 to your computer and use it in GitHub Desktop.
functional synopsis
# mixing imperative and functional code
sum = 0
(1..10).map do |i|
sum += i
end
#=> [1, 3, 6, 10, 15, 21, 28, 36, 45, 55]
(1..10).inject 0 do |acc, i|
next 0 if acc == 6 # effect: set acc = 0 when acc, i == 6, 4
acc + i
end
#=> 45
# lazy select with chunk trick
# you can't write Infinity
r = 1.. 1.0/0
#=> 1..Infinity
# trick with chunk: return nil to filter out the group
r.chunk{|x|x if x%3==2}.take(12).flat_map{|(_,x)|x}
#=> [2, 5, 8, 11, 14, 17, 20, 23, 26, 29, 32, 35]
# lazy in ruby 2.0
(1.. 1.0/0).each.lazy.select{|x| x % 3 == 2}.take(12)
#=> [2, 5, 8, 11, 14, 17, 20, 23, 26, 29, 32, 35]
# pointless
[1, 2, 3].inject :+ #=> 6
# curry
# for proc, the arity is unknown, so you should designate it : curry(2)
[1, 2, 3].map &:+.to_proc.curry(2)[4] #=> [5, 6, 7]
# pattern matching (but we don't have "unmatch")
x, *xs, y = [1, 2, 3, 4]
xs #=> [2, 3]
y #=> 4
# matching regexps
/(?<name>\w+)\ is\ a\ nut./ =~ /Pipilu is a nut./
name #=> Pipilu
# matching structs
Person = Struct.new :first_name, :last_name
person = Person['Yamaguchi', 'Mihiro']
first_name, last_name = *Person
# matching anything
class NiChiGen
attr_accessor :x, :y
# anything responds to :to_ary can be splatted
def to_ary
[((x**2 + y**2) ** 0.5), (Math.atan y / x)]
end
end
point = NiChiGen.new
point.x = 10
point.y = 10
radius, theta = *point # match!
radius #=> 14.1...
theta #=> 0.78
# matching params
def foo bar, (x, *xs, y)
xs
end
foo 1, [2, 3, 4, 5] #=> [3, 4]
('a'..'z').to_a.each_with_index.inject '' do |acc, (char, idx)|
acc << char << idx.to_s
end #=> "a0b1c2d3e4f5g6h7i8j9k10l11m...
# monads
# everything in ruby is a maybe monad, a whole basic block is a state monad
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment