-
Notifications
You must be signed in to change notification settings - Fork 0
/
both.rb
82 lines (70 loc) · 1.26 KB
/
both.rb
1
2
3
4
5
6
7
8
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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
class StopIteration < Exception; end
class Gen
def initialize(obj, itername, *initargs)
@nextcc = callcc do |factory|
consumer = callcc { |cc| factory.call cc }
final = obj.send(itername, *initargs) { |*args|
consumer = callcc { |cc| consumer.call cc, *args }
@nextargs
}
nil
end
end
def next(nextargs = nil)
@nextargs = nextargs
@nextcc or raise StopIteration
@nextcc, rtn = callcc { |cc| @nextcc.call cc }
puts ">> %s, %s" % [@nextcc, rtn]
rtn
end
def each
begin
loop do
@rtn = yield self.next
end
rescue StopIteration
end
end
def sendto(con)
begin
con.next
self.each do |*args|
con.next(*args)
end
rescue StopIteration
end
end
alias >> sendto
end
class Object
def gen(name, *initargs)
Gen.new(self, name, *initargs)
end
end
class MyList
def initialize
@x = []
end
def each
@x.each do |i|
yield i
end
end
def add(n=10000)
n.times do
@x << yield
end
end
def double(con, gen)
loop do
x = con.call
gen.call(x)
gen.call(x*2)
end
end
end
x = MyList.new
(1..5).gen(:each).sendto( x.gen(:add, 3) )
p x
(10..15).gen(:each) >> x.gen(:add, 3)
p x