Class: Stream
- Includes:
- Enumerable
- Defined in:
- lib/raskell/f.rb,
lib/raskell/streams.rb
Instance Attribute Summary collapse
-
#next_item_function ⇒ Object
Returns the value of attribute next_item_function.
-
#state ⇒ Object
Returns the value of attribute state.
Class Method Summary collapse
Instance Method Summary collapse
-
#%(n = 2) ⇒ Object
%2 is odds, rest %2 is evens.
- #&(stream) ⇒ Object
-
#*(stream) ⇒ Object
-
and % are opposites.
-
-
#**(stream, is_zip = false) ⇒ Object
zip or Applicative <*> depending on if there any function values in the array/stream ## or should it be interleave to go with % below? [id, double] * [1,2,3] [1,2,3,2,4,6].
- #+(stream) ⇒ Object
- #-(stream) ⇒ Object
- #==(stream) ⇒ Object
- #===(stream) ⇒ Object
- #[](first, last = -1)) ⇒ Object
-
#^(stream_of_fns, is_cartesian = false) ⇒ Object
Applicative <**> [1,2,3] ** [id, double] [1,2,2,4,3,6] defaults to cartesian product if you haven’t got any procs in there.
- #all?(fn = F.id) ⇒ Boolean
- #another ⇒ Object
- #any?(fn = F.id) ⇒ Boolean
- #call(*args) ⇒ Object
- #deep_clone ⇒ Object
- #each(&fn) ⇒ Object
- #first ⇒ Object
- #foldl(func, unit) ⇒ Object
- #from_stream ⇒ Object
-
#initialize(next_func, state, options = {}) ⇒ Stream
constructor
A new instance of Stream.
- #last ⇒ Object
- #next_item ⇒ Object
- #rest ⇒ Object
- #to_a ⇒ Object
- #to_stream ⇒ Object
-
#|(stream) ⇒ Object
this kind of conflicts with | being function pipelining - maybe change that to use < and > instead of * and | so we can keep ruby-ishness but we’ll still need something for >>=, <**>, <$> and <.> later…
Constructor Details
#initialize(next_func, state, options = {}) ⇒ Stream
Returns a new instance of Stream.
14 15 16 17 18 19 20 |
# File 'lib/raskell/streams.rb', line 14 def initialize(next_func, state, ={}) @next_item_function = next_func @state = state @options = ## step_fn should return one of [:done], [:yield element stream], or [:skip stream] self end |
Instance Attribute Details
#next_item_function ⇒ Object
Returns the value of attribute next_item_function.
13 14 15 |
# File 'lib/raskell/streams.rb', line 13 def next_item_function @next_item_function end |
#state ⇒ Object
Returns the value of attribute state.
13 14 15 |
# File 'lib/raskell/streams.rb', line 13 def state @state end |
Class Method Details
.to_stream(stream) ⇒ Object
56 57 58 |
# File 'lib/raskell/streams.rb', line 56 def self.to_stream(stream) stream end |
Instance Method Details
#%(n = 2) ⇒ Object
%2 is odds, rest %2 is evens. doing % 3 breaks into every third item. % n does every nth as a stream
- odds, evens].(interleave.(xs,ys)) == [xs,ys
1308 1309 1310 |
# File 'lib/raskell/f.rb', line 1308 def %(n=2) F.filter.(->(x) { x % n == 0}).(self) end |
#&(stream) ⇒ Object
1327 1328 1329 |
# File 'lib/raskell/f.rb', line 1327 def &(stream) F.intersect.(self, stream) end |
#*(stream) ⇒ Object
-
and % are opposites
1302 1303 1304 |
# File 'lib/raskell/f.rb', line 1302 def *(stream) ## * and % are opposites F.interleave.(self, stream) end |
#**(stream, is_zip = false) ⇒ Object
zip or Applicative <*> depending on if there any function values in the array/stream ## or should it be interleave to go with % below?
- id, double
- 1,2,3
- 1,2,3,2,4,6
1298 1299 1300 |
# File 'lib/raskell/f.rb', line 1298 def **(stream, is_zip=false) is_zip || !F.any?.(->(x){ x.kind_of? Proc }) ? F.zip.(self, stream) : F.flatmap.(->(f) { F.map.(f) << stream.to_stream }).(self.to_stream) end |
#+(stream) ⇒ Object
1312 1313 1314 |
# File 'lib/raskell/f.rb', line 1312 def +(stream) F.append.(self, stream) end |
#-(stream) ⇒ Object
1316 1317 1318 |
# File 'lib/raskell/f.rb', line 1316 def -(stream) F.difference.(self, stream) end |
#==(stream) ⇒ Object
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/raskell/streams.rb', line 22 def ==(stream) if stream.respond_to?(:to_stream) stream = stream.to_stream next1 = self.another next2 = stream.another equal_so_far = next1 == next2 || (next1.first != :skip && next1[1] == next2[1]) while equal_so_far && !(next1 == [:done] || next2 == [:done]) next1 = next1.last.another next2 = next2.last.another equal_so_far = next1 == next2 end equal_so_far else false end end |
#===(stream) ⇒ Object
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/raskell/streams.rb', line 39 def ===(stream) if stream.respond_to?(:to_stream) stream = stream.to_stream next1 = self.another next2 = stream.another equal_so_far = next1 == next2 || (next1.first != :skip && next1[1] === next2[1]) while equal_so_far && !(next1 == [:done] || next2 == [:done]) next1 = next1.last.another next2 = next2.last.another equal_so_far = next1 === next2 end equal_so_far else false end end |
#[](first, last = -1)) ⇒ Object
1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 |
# File 'lib/raskell/f.rb', line 1254 def [](first, last=-1) if last == -1 i = first F.first * F.drop.(i) elsif first < 0 && last < 0 F.drop_except.(last.abs - 1) * F.drop_except.(first.abs) << self ##todo else raise "" end end |
#^(stream_of_fns, is_cartesian = false) ⇒ Object
Applicative <**>
- 1,2,3
-
** [id, double]
- 1,2,2,4,3,6
-
defaults to cartesian product if you haven’t got any procs in there
1291 1292 1293 |
# File 'lib/raskell/f.rb', line 1291 def ^(stream_of_fns, is_cartesian=false) is_cartesian || !F.any?.(->(x) { x.kind_of? Proc }) ? self.cartesian_product.(stream_of_fns) : F.flatmap.(->(x) { stream_of_fns.(x).to_stream }).(self) end |
#all?(fn = F.id) ⇒ Boolean
1283 1284 1285 |
# File 'lib/raskell/f.rb', line 1283 def all?(fn=F.id) F.all?(fn) << self end |
#another ⇒ Object
82 83 84 85 86 87 88 |
# File 'lib/raskell/streams.rb', line 82 def another item = self.next_item while item.first == :skip item = item.last.next_item end item end |
#any?(fn = F.id) ⇒ Boolean
1279 1280 1281 |
# File 'lib/raskell/f.rb', line 1279 def any?(fn=F.id) F.any?(fn) << self end |
#call(*args) ⇒ Object
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/raskell/streams.rb', line 94 def call(*args) next_fn = ->(next_item) { tag = next_item.first fn = next_item[1] stream = next_item.last if tag == :done [:done] elsif tag == :skip [:skip, Stream.new(next_fn, stream.state)] elsif tag == :yield [:yield, fn.(*args), Stream.new(next_fn, stream.state)] else raise "#{next_item} is a malformed stream result!" end } * self.next_item_function Stream.new(next_fn, self.state) end |
#deep_clone ⇒ Object
1250 1251 1252 |
# File 'lib/raskell/f.rb', line 1250 def deep_clone Stream.new(self.next_item_function, self.state.deep_clone) end |
#each(&fn) ⇒ Object
4 5 6 7 8 9 10 11 |
# File 'lib/raskell/streams.rb', line 4 def each(&fn) item = self.next_item while item != [:done] fn.call(item[1]) if item.first == :yield item = item.last.next_item end self end |
#foldl(func, unit) ⇒ Object
90 91 92 |
# File 'lib/raskell/streams.rb', line 90 def foldl(func, unit) from_stream.foldl(func, unit) end |
#from_stream ⇒ Object
64 65 66 |
# File 'lib/raskell/streams.rb', line 64 def from_stream FromStream.new().(self) end |
#next_item ⇒ Object
72 73 74 75 76 |
# File 'lib/raskell/streams.rb', line 72 def next_item result = @next_item_function.(@state) @state[2] = @state[1].clone.drop(@state[0]) if @options[:type] == "enumerator" result end |
#to_a ⇒ Object
68 69 70 |
# File 'lib/raskell/streams.rb', line 68 def to_a from_stream end |
#to_stream ⇒ Object
60 61 62 |
# File 'lib/raskell/streams.rb', line 60 def to_stream self end |
#|(stream) ⇒ Object
this kind of conflicts with | being function pipelining - maybe change that to use < and > instead of * and | so we can keep ruby-ishness but we’ll still need something for >>=, <**>, <$> and <.> later…
1323 1324 1325 |
# File 'lib/raskell/f.rb', line 1323 def |(stream) # F.union.(self, stream) end |