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 other.



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

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.



47
48
49
# File 'lib/rparsec/functors.rb', line 47

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.



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

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.



62
63
64
# File 'lib/rparsec/functors.rb', line 62

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

#nth(n) ⇒ Object

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



54
55
56
# File 'lib/rparsec/functors.rb', line 54

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.



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

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.



96
97
98
99
# File 'lib/rparsec/functors.rb', line 96

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.



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

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.



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

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