Class: Object

Inherits:
BasicObject
Defined in:
lib/funtools/recursion.rb,
lib/funtools/composition.rb,
lib/funtools/pattern-matching.rb

Instance Method Summary collapse

Instance Method Details

#compose(*f) ⇒ Object

Public: Compose a series of functions.

f - Any number of Procs, Methods, or Symbols which should be composed. If

functions f, g, and h are composed in that order, the result will be
f . g . h -> f(g(h(...)))

Returns a composed Proc.



35
36
37
38
39
# File 'lib/funtools/composition.rb', line 35

def compose(*f)
  f.map do |g|
    g.is_a?(Array) ? ->(n) { g.first.to_proc[n,*g.drop(1)] } : g.to_proc
  end.reduce(&:*)
end

#defpattern(sym) ⇒ Object

Public: Define a method in the current scope which allow pattern matching function declaration to be used.

sym - Symbol defining the name of the method to be created. block - Block containing the logic for the function to be created.

Returns nothing.



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/funtools/pattern-matching.rb', line 11

def defpattern(sym)
  patterns = []
  self.class.send(:define_method, sym) do |*l, &b|
    patterns << ->(*n) do
      ->(*m) do
        flat_m = m.flatten
        flat_n = n.flatten
        if flat_m.length == flat_n.length
          e = flat_m.zip(n.flatten)
          unless e.reject { |e| e[0].nil? || e[0]==e[1] }.any?
            b.call(*flat_n)
          end
        end
      end.(l.flatten)
    end
  end

  yield

  self.send(:define_method, sym) do |*args|
    patterns.each do |pattern|
      result = pattern[args]
      break result unless result.nil?
    end
  end
end

#deftail(sym, &block) ⇒ Object

Public: Define a method in the current scope which will execute a given block recursively until a fixpoint is reached.

sym - Symbol defining the name of the method to be created. block - Block containing the logic for the function to be created.

Returns nothing.



11
12
13
14
15
16
# File 'lib/funtools/recursion.rb', line 11

def deftail(sym, &block)
  self.send(:define_method, sym) do |*n|
    last = nil
    [1].cycle.reduce(n) { |c, e| break c if last == c; last = c; block[c] }
  end
end

#pl(data, *f) ⇒ Object

Public: Mimic the -> macro in Clojure.

data - Any data to be passed to the composed function. f - Any number of Procs, Methods, or Symbols which should be composed.

If functions f, g, and h are composed in that order, the result will
be f . g . h -> f(g(h(...)))

Returns the result of the composed functions, called with data as the argument.



50
51
52
# File 'lib/funtools/composition.rb', line 50

def pl(data, *f)
  compose(*f.reverse)[*[data].flatten]
end