lambda_driver 1.2.0 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/lambda_driver.rb +1 -1
- data/lib/lambda_driver/callable.rb +2 -85
- data/lib/lambda_driver/composable.rb +27 -0
- data/lib/lambda_driver/core_ext.rb +1 -0
- data/lib/lambda_driver/core_ext/class.rb +1 -0
- data/lib/lambda_driver/core_ext/method.rb +6 -1
- data/lib/lambda_driver/core_ext/object.rb +1 -0
- data/lib/lambda_driver/core_ext/proc.rb +6 -1
- data/lib/lambda_driver/core_ext/symbol.rb +7 -1
- data/lib/lambda_driver/core_ext/unbound_method.rb +1 -0
- data/lib/lambda_driver/currring.rb +10 -0
- data/lib/lambda_driver/currying.rb +18 -5
- data/lib/lambda_driver/disjunction.rb +1 -0
- data/lib/lambda_driver/flipable.rb +39 -0
- data/lib/lambda_driver/liftable.rb +1 -0
- data/lib/lambda_driver/mzero.rb +1 -0
- data/lib/lambda_driver/op.rb +1 -0
- data/lib/lambda_driver/proc_convertable.rb +6 -0
- data/lib/lambda_driver/revapply.rb +1 -0
- data/lib/lambda_driver/version.rb +2 -1
- data/lib/lambda_driver/with_args.rb +24 -0
- data/spec/class_spec.rb +1 -0
- data/spec/disjunction_spec.rb +1 -0
- data/spec/lambda_spec.rb +2 -0
- data/spec/method_spec.rb +4 -0
- data/spec/op_spec.rb +1 -0
- data/spec/proc_spec.rb +2 -0
- data/spec/revapply_spec.rb +1 -0
- data/spec/shared/composable_spec.rb +11 -5
- data/spec/shared/liftable.rb +1 -0
- data/spec/spec_helper.rb +1 -0
- data/spec/symbol_spec.rb +2 -1
- data/spec/unbound_method_spec.rb +1 -0
- metadata +7 -8
data/lib/lambda_driver.rb
CHANGED
@@ -1,94 +1,11 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
1
2
|
module LambdaDriver::Callable
|
2
3
|
|
3
|
-
def
|
4
|
+
def <(*args, &block)
|
4
5
|
if block_given?
|
5
6
|
self.to_proc.call(*args, &block)
|
6
7
|
else
|
7
8
|
self.to_proc.call(*args)
|
8
9
|
end
|
9
10
|
end
|
10
|
-
|
11
|
-
# Returns new lambda which composed self and given function.
|
12
|
-
# A composed proc called with args, executes `self.(g(*args)).
|
13
|
-
#
|
14
|
-
# f = lamdba{|x| x.to_s }
|
15
|
-
# g = lambda{|y| y.length }
|
16
|
-
# h = f compose g
|
17
|
-
# h.(:hoge) # => 4
|
18
|
-
#
|
19
|
-
# This method is aliased as `<<`.
|
20
|
-
#
|
21
|
-
# f << g # => f.compose(g)
|
22
|
-
#
|
23
|
-
def compose(g)
|
24
|
-
lambda{|*args| self.to_proc.call(g.to_proc.call(*args)) }
|
25
|
-
end
|
26
|
-
|
27
|
-
# g compose self
|
28
|
-
def >>(g)
|
29
|
-
g.to_proc << self
|
30
|
-
end
|
31
|
-
|
32
|
-
# Returns partially applied function that has 2nd and more parameters
|
33
|
-
# fixed by given *args.
|
34
|
-
#
|
35
|
-
# f = lamdba{|x, y, z| [x, y, z]}
|
36
|
-
# h = f.with_args(:a, :b)
|
37
|
-
# h.(:c) # => [:c, :a, :b]
|
38
|
-
#
|
39
|
-
# This method is aliased as `*`.
|
40
|
-
#
|
41
|
-
# f * :foo # => f.with_args(:foo)
|
42
|
-
#
|
43
|
-
def with_args(*args)
|
44
|
-
lambda{|v|
|
45
|
-
self.to_proc.call(*([v] + args))
|
46
|
-
}
|
47
|
-
end
|
48
|
-
|
49
|
-
# Returns function whose parameter order spawed 1st for 2nd.
|
50
|
-
# A result of filped fuction is curried by Proc#curry.
|
51
|
-
#
|
52
|
-
# f = lamdba{|x, y, z| [x, y, z]}
|
53
|
-
# h = f.flip
|
54
|
-
# h.(:a).(:b).(:c) # => [:b, :a, :c]
|
55
|
-
#
|
56
|
-
# If arguments is var-args, pass explicitly arity to curring.
|
57
|
-
#
|
58
|
-
# p = Proc.new{|*args| args.inspect }
|
59
|
-
# p.flip(3).call(:a).(:b).(:c) # => "[:b, :a, :c]"
|
60
|
-
# p.flip(4).call(:a).(:b).(:c).(:d) # => "[:b, :a, :c, :d]"
|
61
|
-
#
|
62
|
-
# If arity is 0 or 1, flip returns itself.
|
63
|
-
#
|
64
|
-
# This method is aliased as `~@`.
|
65
|
-
#
|
66
|
-
# ~f # => f.filp
|
67
|
-
#
|
68
|
-
def flip(arity = nil)
|
69
|
-
f = self.to_proc
|
70
|
-
return self if (0..1).include?(f.arity)
|
71
|
-
return self if f.arity == -1 && arity.nil?
|
72
|
-
|
73
|
-
curried = f.curry(arity)
|
74
|
-
lambda{|x|
|
75
|
-
lambda{|y|
|
76
|
-
g = curried[y]
|
77
|
-
(g.respond_to? :call) ? g[x] : g
|
78
|
-
}
|
79
|
-
}
|
80
|
-
end
|
81
|
-
|
82
|
-
def curry(arity = nil)
|
83
|
-
self.to_proc.curry(arity)
|
84
|
-
end
|
85
|
-
|
86
|
-
def self.included(klass)
|
87
|
-
klass.send(:alias_method, :+@, :to_proc)
|
88
|
-
klass.send(:alias_method, :<, :call)
|
89
|
-
klass.send(:alias_method, :<<, :compose)
|
90
|
-
klass.send(:alias_method, :*, :with_args)
|
91
|
-
klass.send(:alias_method, :~@, :flip)
|
92
|
-
klass.send(:alias_method, :%, :curry)
|
93
|
-
end
|
94
11
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
module LambdaDriver::Composable
|
3
|
+
# Returns new lambda which composed self and given function.
|
4
|
+
# A composed proc called with args, executes `self.(g(*args)).
|
5
|
+
#
|
6
|
+
# f = lamdba{|x| x.to_s }
|
7
|
+
# g = lambda{|y| y.length }
|
8
|
+
# h = f compose g
|
9
|
+
# h.(:hoge) # => 4
|
10
|
+
#
|
11
|
+
# This method is aliased as `<<`.
|
12
|
+
#
|
13
|
+
# f << g # => f.compose(g)
|
14
|
+
#
|
15
|
+
def compose(g)
|
16
|
+
lambda{|*args| self.to_proc.call(g.to_proc.call(*args)) }
|
17
|
+
end
|
18
|
+
|
19
|
+
# g compose self
|
20
|
+
def >>(g)
|
21
|
+
g.to_proc << self
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.included(klass)
|
25
|
+
klass.send(:alias_method, :<<, :compose)
|
26
|
+
end
|
27
|
+
end
|
@@ -1,5 +1,10 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
1
2
|
class Method
|
2
3
|
include LambdaDriver::Callable
|
3
|
-
include LambdaDriver::
|
4
|
+
include LambdaDriver::Composable
|
5
|
+
include LambdaDriver::WithArgs
|
6
|
+
include LambdaDriver::Flipable
|
7
|
+
include LambdaDriver::ProcConvertable
|
8
|
+
include LambdaDriver::Currying
|
4
9
|
include LambdaDriver::Liftable
|
5
10
|
end
|
@@ -1,5 +1,10 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
1
2
|
class Proc
|
2
3
|
include LambdaDriver::Callable
|
3
|
-
include LambdaDriver::
|
4
|
+
include LambdaDriver::Composable
|
5
|
+
include LambdaDriver::WithArgs
|
6
|
+
include LambdaDriver::Flipable
|
7
|
+
include LambdaDriver::ProcConvertable
|
8
|
+
include LambdaDriver::Currying
|
4
9
|
include LambdaDriver::Liftable
|
5
10
|
end
|
@@ -1,6 +1,12 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
1
2
|
class Symbol
|
2
3
|
include LambdaDriver::Callable
|
3
|
-
include LambdaDriver::
|
4
|
+
include LambdaDriver::Composable
|
5
|
+
include LambdaDriver::WithArgs
|
6
|
+
include LambdaDriver::Flipable
|
7
|
+
include LambdaDriver::ProcConvertable
|
8
|
+
include LambdaDriver::Currying
|
9
|
+
include LambdaDriver::Liftable
|
4
10
|
|
5
11
|
def to_method
|
6
12
|
lambda{|obj| obj._(self) }
|
@@ -1,10 +1,18 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
1
2
|
module LambdaDriver::Currying
|
2
|
-
def curry(arity = nil)
|
3
|
-
f = self.to_proc
|
4
|
-
arity ||= __arity(f)
|
5
|
-
return f if arity == 0
|
6
3
|
|
7
|
-
|
4
|
+
if RUBY_VERSION < '1.9.0'
|
5
|
+
def curry(arity = nil)
|
6
|
+
f = self.to_proc
|
7
|
+
arity ||= __arity(f)
|
8
|
+
return f if arity == 0
|
9
|
+
|
10
|
+
lambda{|arg| __curry(f, arity, arg, []) }
|
11
|
+
end
|
12
|
+
else
|
13
|
+
def curry(arity = nil)
|
14
|
+
self.to_proc.curry(arity)
|
15
|
+
end
|
8
16
|
end
|
9
17
|
|
10
18
|
private
|
@@ -17,4 +25,9 @@ module LambdaDriver::Currying
|
|
17
25
|
return f.call(*args) if arity == 1
|
18
26
|
lambda{|arg| __curry(f, arity - 1, arg, args) }
|
19
27
|
end
|
28
|
+
|
29
|
+
|
30
|
+
def self.included(klass)
|
31
|
+
klass.send(:alias_method, :%, :curry)
|
32
|
+
end
|
20
33
|
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
module LambdaDriver::Flipable
|
3
|
+
# Returns function whose parameter order spawed 1st for 2nd.
|
4
|
+
# A result of filped fuction is curried by Proc#curry.
|
5
|
+
#
|
6
|
+
# f = lamdba{|x, y, z| [x, y, z]}
|
7
|
+
# h = f.flip
|
8
|
+
# h.(:a).(:b).(:c) # => [:b, :a, :c]
|
9
|
+
#
|
10
|
+
# If arguments is var-args, pass explicitly arity to curring.
|
11
|
+
#
|
12
|
+
# p = Proc.new{|*args| args.inspect }
|
13
|
+
# p.flip(3).call(:a).(:b).(:c) # => "[:b, :a, :c]"
|
14
|
+
# p.flip(4).call(:a).(:b).(:c).(:d) # => "[:b, :a, :c, :d]"
|
15
|
+
#
|
16
|
+
# If arity is 0 or 1, flip returns itself.
|
17
|
+
#
|
18
|
+
# This method is aliased as `~@`.
|
19
|
+
#
|
20
|
+
# ~f # => f.filp
|
21
|
+
#
|
22
|
+
def flip(arity = nil)
|
23
|
+
f = self.to_proc
|
24
|
+
return self if (0..1).include?(f.arity)
|
25
|
+
return self if f.arity == -1 && arity.nil?
|
26
|
+
|
27
|
+
curried = f.curry(arity)
|
28
|
+
lambda{|x|
|
29
|
+
lambda{|y|
|
30
|
+
g = curried[y]
|
31
|
+
(g.respond_to? :call) ? g[x] : g
|
32
|
+
}
|
33
|
+
}
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.included(klass)
|
37
|
+
klass.send(:alias_method, :~@, :flip)
|
38
|
+
end
|
39
|
+
end
|
data/lib/lambda_driver/mzero.rb
CHANGED
data/lib/lambda_driver/op.rb
CHANGED
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
module LambdaDriver::WithArgs
|
3
|
+
|
4
|
+
# Returns partially applied function that has 2nd and more parameters
|
5
|
+
# fixed by given *args.
|
6
|
+
#
|
7
|
+
# f = lamdba{|x, y, z| [x, y, z]}
|
8
|
+
# h = f.with_args(:a, :b)
|
9
|
+
# h.(:c) # => [:c, :a, :b]
|
10
|
+
#
|
11
|
+
# This method is aliased as `*`.
|
12
|
+
#
|
13
|
+
# f * :foo # => f.with_args(:foo)
|
14
|
+
#
|
15
|
+
def with_args(*args)
|
16
|
+
lambda{|v|
|
17
|
+
self.to_proc.call(*([v] + args))
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.included(klass)
|
22
|
+
klass.send(:alias_method, :*, :with_args)
|
23
|
+
end
|
24
|
+
end
|
data/spec/class_spec.rb
CHANGED
data/spec/disjunction_spec.rb
CHANGED
data/spec/lambda_spec.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
1
2
|
require 'spec_helper'
|
2
3
|
|
3
4
|
describe 'lambda' do
|
@@ -54,6 +55,7 @@ describe 'lambda' do
|
|
54
55
|
subject { lambda{|x| x.to_s + "_f"} }
|
55
56
|
|
56
57
|
it_should_behave_like 'call'
|
58
|
+
it_should_behave_like 'call(<)'
|
57
59
|
end
|
58
60
|
|
59
61
|
describe 'ailases' do
|
data/spec/method_spec.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
1
2
|
require 'spec_helper'
|
2
3
|
|
3
4
|
describe Method do
|
@@ -74,6 +75,9 @@ describe Method do
|
|
74
75
|
it_should_behave_like 'call' do
|
75
76
|
let(:x) { "foo" }
|
76
77
|
end
|
78
|
+
it_should_behave_like 'call(<)' do
|
79
|
+
let(:x) { "foo" }
|
80
|
+
end
|
77
81
|
end
|
78
82
|
|
79
83
|
describe 'ailases' do
|
data/spec/op_spec.rb
CHANGED
data/spec/proc_spec.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
1
2
|
require 'spec_helper'
|
2
3
|
|
3
4
|
describe Proc do
|
@@ -54,6 +55,7 @@ describe Proc do
|
|
54
55
|
subject { Proc.new{|x| x.to_s + "_f"} }
|
55
56
|
|
56
57
|
it_should_behave_like 'call'
|
58
|
+
it_should_behave_like 'call(<)'
|
57
59
|
end
|
58
60
|
|
59
61
|
describe 'ailases' do
|
data/spec/revapply_spec.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
1
2
|
require 'spec_helper'
|
2
3
|
|
3
4
|
shared_examples_for 'composable' do
|
@@ -93,7 +94,7 @@ shared_examples_for 'flip(arity=1)' do
|
|
93
94
|
}
|
94
95
|
|
95
96
|
it(' f.flip.call(x) returns proc ') {
|
96
|
-
subject.flip.call(y) == subject.call(y)
|
97
|
+
subject.flip.to_proc.call(y) == subject.to_proc.call(y)
|
97
98
|
}
|
98
99
|
end
|
99
100
|
|
@@ -106,7 +107,7 @@ shared_examples_for 'flip(varargs)' do
|
|
106
107
|
}
|
107
108
|
|
108
109
|
it('f.flip(2).call(x) returns proc ') {
|
109
|
-
subject.flip(2).call(y) == subject.call(y)
|
110
|
+
subject.flip(2).call(y) == subject.to_proc.call(y)
|
110
111
|
}
|
111
112
|
|
112
113
|
it('~f.flip(2).call(x).call(y) should be f.call(y,x)'){
|
@@ -151,16 +152,21 @@ end
|
|
151
152
|
|
152
153
|
shared_examples_for 'call' do
|
153
154
|
it { should respond_to :call}
|
154
|
-
it { should respond_to :<}
|
155
155
|
|
156
156
|
let(:x) { :foo }
|
157
157
|
|
158
158
|
it('f.call(x) == f.call(x)'){
|
159
159
|
subject.call(x).should == subject.call(x)
|
160
160
|
}
|
161
|
+
end
|
162
|
+
|
163
|
+
shared_examples_for 'call(<)' do
|
164
|
+
it { should respond_to :<}
|
165
|
+
|
166
|
+
let(:x) { :foo }
|
161
167
|
|
162
168
|
it('(f < x) == f.call(x)'){
|
163
|
-
(subject < x).should == subject.call(x)
|
169
|
+
(subject < x).should == subject.to_proc.call(x)
|
164
170
|
}
|
165
171
|
end
|
166
172
|
|
@@ -170,7 +176,7 @@ shared_examples_for 'aliases' do
|
|
170
176
|
let(:g) { lambda{|x| (x.to_s * 2).to_s + "_g" } }
|
171
177
|
|
172
178
|
it('(~f < x) should be f.flip.call(x)'){
|
173
|
-
(~subject < x).should == subject.flip.call(x)
|
179
|
+
(~subject < x).should == subject.flip.to_proc.call(x)
|
174
180
|
}
|
175
181
|
|
176
182
|
it('(f << g < x) should f.compose(g).call(x)'){
|
data/spec/shared/liftable.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
data/spec/symbol_spec.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
1
2
|
require 'spec_helper'
|
2
3
|
|
3
4
|
describe Symbol do
|
@@ -46,7 +47,7 @@ describe Symbol do
|
|
46
47
|
describe '#call' do
|
47
48
|
subject { :to_s }
|
48
49
|
|
49
|
-
it_should_behave_like 'call'
|
50
|
+
it_should_behave_like 'call(<)'
|
50
51
|
end
|
51
52
|
|
52
53
|
describe 'ailases' do
|
data/spec/unbound_method_spec.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lambda_driver
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2.
|
4
|
+
version: 1.2.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-01-
|
12
|
+
date: 2014-01-29 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
@@ -44,6 +44,7 @@ files:
|
|
44
44
|
- lambda_driver.gemspec
|
45
45
|
- lib/lambda_driver.rb
|
46
46
|
- lib/lambda_driver/callable.rb
|
47
|
+
- lib/lambda_driver/composable.rb
|
47
48
|
- lib/lambda_driver/core_ext.rb
|
48
49
|
- lib/lambda_driver/core_ext/class.rb
|
49
50
|
- lib/lambda_driver/core_ext/method.rb
|
@@ -51,13 +52,17 @@ files:
|
|
51
52
|
- lib/lambda_driver/core_ext/proc.rb
|
52
53
|
- lib/lambda_driver/core_ext/symbol.rb
|
53
54
|
- lib/lambda_driver/core_ext/unbound_method.rb
|
55
|
+
- lib/lambda_driver/currring.rb
|
54
56
|
- lib/lambda_driver/currying.rb
|
55
57
|
- lib/lambda_driver/disjunction.rb
|
58
|
+
- lib/lambda_driver/flipable.rb
|
56
59
|
- lib/lambda_driver/liftable.rb
|
57
60
|
- lib/lambda_driver/mzero.rb
|
58
61
|
- lib/lambda_driver/op.rb
|
62
|
+
- lib/lambda_driver/proc_convertable.rb
|
59
63
|
- lib/lambda_driver/revapply.rb
|
60
64
|
- lib/lambda_driver/version.rb
|
65
|
+
- lib/lambda_driver/with_args.rb
|
61
66
|
- spec/class_spec.rb
|
62
67
|
- spec/disjunction_spec.rb
|
63
68
|
- spec/lambda_spec.rb
|
@@ -82,18 +87,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
82
87
|
- - ! '>='
|
83
88
|
- !ruby/object:Gem::Version
|
84
89
|
version: '0'
|
85
|
-
segments:
|
86
|
-
- 0
|
87
|
-
hash: -920517596245893888
|
88
90
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
89
91
|
none: false
|
90
92
|
requirements:
|
91
93
|
- - ! '>='
|
92
94
|
- !ruby/object:Gem::Version
|
93
95
|
version: '0'
|
94
|
-
segments:
|
95
|
-
- 0
|
96
|
-
hash: -920517596245893888
|
97
96
|
requirements: []
|
98
97
|
rubyforge_project:
|
99
98
|
rubygems_version: 1.8.23
|