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.



33
34
35
36
37
# File 'lib/funtools/composition.rb', line 33

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.



9
10
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 9

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

  message   = :define_method if respond_to?(:define_method, true)
  message ||= :define_singleton_method
  self.send(message, 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.



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

def deftail(sym, &block)
  message   = :define_method if respond_to?(:define_method, true)
  message ||= :define_singleton_method
  self.send(message, 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.



48
49
50
# File 'lib/funtools/composition.rb', line 48

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