Class: Stream

Inherits:
Object show all
Includes:
Enumerable
Defined in:
lib/raskell/f.rb,
lib/raskell/streams.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

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, options={})
  @next_item_function = next_func
  @state = state
  @options = options
  ## step_fn should return one of [:done], [:yield element stream], or [:skip stream]
  self
end

Instance Attribute Details

#next_item_functionObject

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

#stateObject

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

Returns:

  • (Boolean)


1283
1284
1285
# File 'lib/raskell/f.rb', line 1283

def all?(fn=F.id)
  F.all?(fn) << self   
end

#anotherObject



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

Returns:

  • (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_cloneObject



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

#firstObject



1267
1268
1269
# File 'lib/raskell/f.rb', line 1267

def first
  F.first.(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_streamObject



64
65
66
# File 'lib/raskell/streams.rb', line 64

def from_stream
  FromStream.new().(self)
end

#lastObject



1271
1272
1273
# File 'lib/raskell/f.rb', line 1271

def last
  F.last.(self)
end

#next_itemObject



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

#restObject



1275
1276
1277
# File 'lib/raskell/f.rb', line 1275

def rest
  F.rest.(self)
end

#to_aObject



68
69
70
# File 'lib/raskell/streams.rb', line 68

def to_a
  from_stream
end

#to_streamObject



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