Module: RParsec::Functors

Extended by:
Functors
Included in:
Functors, Parser
Defined in:
lib/rparsec/functors.rb

Overview

This module provides frequently used functors.

Constant Summary collapse

Id =
proc { |x| x }
Idn =
proc { |*x| x }
Neg =
proc { |x| -x }
Inc =
proc { |x| x + 1 }
Succ =
proc { |x| x.succ }
Dec =
proc { |x| x - 1 }
Plus =
proc { |x, y| x + y }
Minus =
proc { |x, y| x - y }
Mul =
proc { |x, y| x * y }
Div =
proc { |x, y| x / y }
Mod =
proc { |x, y| x % y }
Power =
proc { |x, y| x**y }
Not =
proc { |x, _y| !x }
And =
proc { |x, y| x && y }
Or =
proc { |x, y| x || y }
Xor =
proc { |x, y| x ^ y }
BitAnd =
proc { |x, y| x & y }
Union =
proc { |x, y| x | y }
Match =
proc { |x, y| x =~ y }
Eq =
proc { |x, y| x == y }
Ne =
proc { |x, y| x != y }
Lt =
proc { |x, y| x < y }
Gt =
proc { |x, y| x > y }
Le =
proc { |x, y| x <= y }
Ge =
proc { |x, y| x >= y }
Compare =
proc { |x, y| x <=> y }
Call =
proc { |x, y| x.call(y) }
Feed =
proc { |x, y| y.call(x) }
Fst =
proc { |x, _| x }
Snd =
proc { |_, x| x }
At =
proc { |x, y| x[y] }
To_a =
proc { |x| x.to_a }
To_s =
proc { |x| x.to_s }
To_i =
proc { |x| x.to_i }
To_sym =
proc { |x| x.to_sym }
To_f =
proc { |x| x.to_f }

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.make_curry(arity, &block) ⇒ Object



160
161
162
163
164
165
166
167
# File 'lib/rparsec/functors.rb', line 160

def self.make_curry(arity, &block)
  return block if arity <= 1
  proc do |x|
    make_curry(arity - 1) do |*rest|
      block.call(*rest.insert(0, x))
    end
  end
end

.make_reverse_curry(arity, &block) ⇒ Object



169
170
171
172
173
174
175
176
# File 'lib/rparsec/functors.rb', line 169

def self.make_reverse_curry(arity, &block)
  return block if arity <= 1
  proc do |x|
    make_reverse_curry(arity - 1) do |*rest|
      block.call(*rest << x)
    end
  end
end

Instance Method Details

#compose(f1, f2) ⇒ Object

Create a Proc, when called, the parameter is first passed into f2, f1 is called in turn with the return value from f2.



72
73
74
# File 'lib/rparsec/functors.rb', line 72

def compose(f1, f2)
  proc { |*x| f1.call(f2.call(*x)) }
end

#const(v) ⇒ Object

Get a Proc, when called, always return the given value.



49
50
51
# File 'lib/rparsec/functors.rb', line 49

def const(v)
  proc { |_| v }
end

#curry(arity, &block) ⇒ Object

Create a Proc that’s curriable. When curried, parameters are passed in from left to right. i.e. curry(closure).call(a).call(b) is quivalent to closure.call(a,b). block is encapsulated under the hood to perform the actual job when currying is done. arity explicitly specifies the number of parameters to curry.



84
85
86
87
# File 'lib/rparsec/functors.rb', line 84

def curry(arity, &block)
  fail "cannot curry for unknown arity" if arity < 0
  Functors.make_curry(arity, &block)
end

#flip(&block) ⇒ Object

Create a Proc, which expects the two parameters in the reverse order of block.



64
65
66
# File 'lib/rparsec/functors.rb', line 64

def flip(&block)
  proc { |x, y| block.call(y, x) }
end

#nth(n) ⇒ Object

Get a Proc, when called, return the nth parameter.



56
57
58
# File 'lib/rparsec/functors.rb', line 56

def nth(n)
  proc { |*args| args[n] }
end

#power(n, &block) ⇒ Object

Create a Proc, when called, repeatedly call block for n times. At each iteration, return value from the previous iteration is used as parameter.



148
149
150
151
152
153
154
155
156
# File 'lib/rparsec/functors.rb', line 148

def power(n, &block)
  return const(nil) if n <= 0
  return block if n == 1
  proc do |*args|
    result = block.call(*args)
    (n - 1).times { result = block.call(result) }
    result
  end
end

#repeat(n, &block) ⇒ Object

Create a Proc, when called, repeatedly call block for n times. The same arguments are passed to each invocation.



135
136
137
138
139
140
141
# File 'lib/rparsec/functors.rb', line 135

def repeat(n, &block)
  proc do |*args|
    result = nil
    n.times { result = block.call(*args) }
    result
  end
end

#reverse_curry(arity, &block) ⇒ Object

Create a Proc that’s curriable. When curried, parameters are passed in from right to left. i.e. reverse_curry(closure).call(a).call(b) is quivalent to closure.call(b, a). block is encapsulated under the hood to perform the actual job when currying is done. arity explicitly specifies the number of parameters to curry.



98
99
100
101
# File 'lib/rparsec/functors.rb', line 98

def reverse_curry(arity, &block)
  fail "cannot curry for unknown arity" if arity < 0
  Functors.make_reverse_curry(arity, &block)
end

#reverse_uncurry(&block) ⇒ Object

Uncurry a reverse curried closure.



120
121
122
123
124
125
126
127
128
129
# File 'lib/rparsec/functors.rb', line 120

def reverse_uncurry(&block)
  return block unless block.arity == 1
  proc do |*args|
    result = block
    args.reverse_each do |a|
      result = result.call(a)
    end
    result
  end
end

#uncurry(&block) ⇒ Object

Uncurry a curried closure.



106
107
108
109
110
111
112
113
114
115
# File 'lib/rparsec/functors.rb', line 106

def uncurry(&block)
  return block unless block.arity == 1
  proc do |*args|
    result = block
    args.each do |a|
      result = result.call(a)
    end
    result
  end
end