ex_aequo_streams 0.1.0 → 0.1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b0fb93ecf83932800fa74ebfda93021116c2ed3eaa75e52ab1ba24570d4b5d52
4
- data.tar.gz: 78ae3b27a6adc254cd0b7065358c72474533a9d4a7845a34ad925db41286a90e
3
+ metadata.gz: ae3e6d30027b024529d7e8ca5046e188e81fd8c9803869c08324974a8303ecfe
4
+ data.tar.gz: 4ba3a1aecd827bd6bc1cd5b06b7bb50e1292041d87a0e906b9f4ca8a8a69239f
5
5
  SHA512:
6
- metadata.gz: df1e6ea0cea3264a5e15141a63fa2d85fcb73395633072ac4cf0d2b379f4df3fa50bde6031503ae8bcfa1d546d062f3b2f8b428568617539abc9618eed70de04
7
- data.tar.gz: 42cdce54adfcc06a648f35a5d05fc5c677ad72fbb9dd140f92e2567c6e0c2edfb1520b93fa2a71a03a60547281844a7fbb658a8ec323787317da4d7deab81405
6
+ metadata.gz: a03fba937252d9fd90d637b6aa58622fbb75640029fa9c1cbfd7c8d538aeaa09e4c3ee06551aaea500ad153760efe2142e965df00d888f4b35a4faf0e6322829
7
+ data.tar.gz: 6c88b678b4b5e9b62ec05f92a3ee4aca8c85030b53a8cda1553197ac882f53f9265071ef888839ed1a252567417ba672dbca68e009e31e5d7eeba40d3a35cd7d
@@ -31,23 +31,23 @@ module ExAequo
31
31
 
32
32
  def interleave(*streams)
33
33
  case streams
34
- in []
35
- empty
36
34
  in [hs, *tsts]
37
35
  return interleave(*tsts) if hs.empty?
38
36
  cons_stream(hs.head) { interleave(*[*tsts, hs.tail]) }
37
+ else
38
+ empty
39
39
  end
40
40
  end
41
41
 
42
42
  def interleave_n(*streams)
43
43
  case streams
44
- in []
45
- empty
46
44
  in [[s, c], *r]
47
45
  return interleave_n(*r) if s.empty?
48
46
 
49
47
  s.take_and_drop(c) => sh, sr
50
48
  prefixed(*sh) { interleave_n(*[*r, [sr, c]]) }
49
+ else
50
+ empty
51
51
  end
52
52
  end
53
53
 
@@ -62,10 +62,10 @@ module ExAequo
62
62
 
63
63
  def prefixed(value, *values, &blk)
64
64
  case values
65
- in []
66
- new(value, &blk)
67
65
  in [next_head, *next_tails]
68
66
  new(value) { prefixed(next_head, *next_tails, &blk) }
67
+ else
68
+ new(value, &blk)
69
69
  end
70
70
  end
71
71
 
@@ -85,10 +85,6 @@ module ExAequo
85
85
  fh.close rescue nil
86
86
  empty
87
87
  end
88
-
89
- def get_heads(streams)
90
- heads = streams.map(&:head)
91
- end
92
88
  end
93
89
  end
94
90
  end
@@ -7,14 +7,25 @@ module ExAequo
7
7
  class Empty < ExAequo::Streams::Stream
8
8
  include Singleton
9
9
 
10
- def empty? = true
10
+ def advance(_) = self
11
+ def drop_until(*) = self
12
+ def drop_while(*) = self
11
13
  def empty = self
14
+ def empty? = true
12
15
  def force = []
16
+ def func_drop_until(*) = self
17
+ def func_drop_while(*) = self
13
18
  def func_flat_map(_) = self
19
+ def func_take_stream(_) = self
14
20
  def head = raise StopIteration, "must not access head of the empty stream"
15
21
  def head_stream(_) = self
16
22
  def head_tail = raise StopIteration, "must not access head of the empty stream"
17
23
  def tail = self
24
+ def take_stream(_) = self
25
+ def take_until(*) = []
26
+ def take_until_stream(*) = self
27
+ def take_while(*) = []
28
+ def take_while_stream(*) = self
18
29
 
19
30
  private
20
31
  def initialize = nil
@@ -0,0 +1,84 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ExAequo
4
+ module Streams
5
+ class Stream
6
+ module FuncMethods
7
+ def func_drop_until(f, advance: 0)
8
+ current = self
9
+ loop do
10
+ return empty if current.empty?
11
+ return current.drop(advance) if f.(current.head)
12
+ current = current.tail
13
+ end
14
+ end
15
+
16
+ def func_drop_while(f, advance: 0)
17
+ if f.(head)
18
+ return empty if tail.empty?
19
+ self.class.new(tail.head) { tail.tail }
20
+ .func_drop_while(f, advance:)
21
+ else
22
+ drop(advance)
23
+ end
24
+ end
25
+
26
+ def func_flat_map(f)
27
+ expanded = f.(head)
28
+ # TODO: allow expanded to ab any enumarable by defining a general tail function
29
+ raise ArgumentError, "not a stream #{expanded.inspect}" unless self.class === expanded
30
+
31
+ # p(expanded: expanded.force.inspect)
32
+ return tail.func_flat_map(f) if expanded.empty?
33
+ self.class.new(expanded.head) {
34
+ self.class.interleave(tail.func_flat_map(f), expanded.tail)
35
+ }
36
+ end
37
+
38
+ def func_map(f)
39
+ return self.class.empty if empty?
40
+ self.class.new(f.(head)) {
41
+ tail.func_map(f)
42
+ }
43
+ end
44
+
45
+ def func_take_stream(more)
46
+ return empty if more.zero?
47
+ cons_stream(head) { tail.func_take_stream(more.pred) }
48
+ end
49
+
50
+ def func_take_until(f, more: 0)
51
+ result = []
52
+ current = self
53
+ loop do
54
+ return result if current.empty?
55
+ return result + current.take(more) if f.(current.head)
56
+ result << current.head
57
+ current = current.tail
58
+ end
59
+ end
60
+
61
+ def func_take_until_stream(f, more: 0)
62
+ if f.(head)
63
+ func_take_stream(more)
64
+ else
65
+ cons_stream(head) {
66
+ tail.func_take_until_stream(f, more:)
67
+ }
68
+ end
69
+ end
70
+
71
+ def func_take_while_stream(f, more: 0)
72
+ if f.(head)
73
+ cons_stream(head) {
74
+ tail.func_take_while_stream(f, more:)
75
+ }
76
+ else
77
+ func_take_stream(more)
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
84
+ # SPDX-License-Identifier: AGPL-3.0-or-later
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ExAequo
4
+ module Streams
5
+ class Stream
6
+ module StreamMethods
7
+
8
+ def append(*streams)
9
+ case streams
10
+ in [sfirst, *srest]
11
+ return sfirst.append(*srest) if empty?
12
+ self.class.new(head) { tail.append(*streams) }
13
+ else
14
+ self
15
+ end
16
+ end
17
+
18
+ def drop(n)
19
+ n.times.inject(self) { |s,| s.tail }
20
+ end
21
+
22
+ def drop_until(fn_desc=nil, advance: 0, &blk)
23
+ f = Fn.mk_fun_or(fn_desc, &blk)
24
+ func_drop_until(f, advance:)
25
+ end
26
+
27
+ def drop_while(fn_desc=nil, advance: 0, &blk)
28
+ f = Fn.mk_fun_or(fn_desc, &blk)
29
+ func_drop_while(f, advance:)
30
+ end
31
+
32
+ def head_stream(n)
33
+ return empty if n < 1
34
+ self.class.new(head) { tail.head_stream(n.pred) }
35
+ end
36
+
37
+ def flat_map(fn_desc=nil, &blk)
38
+ f = Fn.mk_fun_or(fn_desc, &blk)
39
+ func_flat_map(f)
40
+ end
41
+
42
+ def map(fn_desc=nil, &blk)
43
+ f = Fn.mk_fun_or(fn_desc, &blk)
44
+ func_map(f)
45
+ end
46
+
47
+ def take_until_stream(fn_desc=nil, more: 0, &blk)
48
+ f = Fn.mk_fun_or(fn_desc, &blk)
49
+ func_take_until_stream(f, more:)
50
+ end
51
+
52
+ def take_while_stream(fn_desc=nil, more: 0, &blk)
53
+ f = Fn.mk_fun_or(fn_desc, &blk)
54
+ func_take_while_stream(f, more:)
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+ # SPDX-License-Identifier: AGPL-3.0-or-later
@@ -9,69 +9,23 @@ module ExAequo
9
9
  class Stream
10
10
 
11
11
  extend ClassMethods
12
+ include FuncMethods
13
+ include StreamMethods
12
14
 
13
15
  attr_reader :head
14
16
 
15
- def append(*streams)
16
- case streams
17
- in []
18
- self
19
- in [sfirst, *srest]
20
- return sfirst.append(*srest) if empty?
21
- self.class.new(head) { tail.append(*streams) }
22
- end
23
- end
24
-
25
- def drop(n)
26
- n.times.inject(self) { |s,| s.tail }
27
- end
28
-
29
17
  def empty? = false
30
18
 
31
19
  def empty = self.class.empty
32
20
 
33
21
  def force = take_while { true }
34
22
 
35
- def head_stream(n)
36
- return empty if n < 1
37
- self.class.new(head) { tail.head_stream(n.pred) }
38
- end
39
-
40
23
  def head_tail = [head, tail]
41
24
 
42
- def flat_map(fn_desc=nil, &blk)
43
- f = Fn.mk_fun_or(fn_desc, &blk)
44
- func_flat_map(f)
45
- end
46
-
47
- def func_flat_map(f)
48
- expanded = f.(head)
49
- # TODO: allow expanded to ab any enumarable by defining a general tail function
50
- raise ArgumentError, "not a stream #{expaneded.inspect}" unless self.class === expanded
51
-
52
- # p(expanded: expanded.force.inspect)
53
- return tail.func_flat_map(f) if expanded.empty?
54
- self.class.new(expanded.head) {
55
- self.class.interleave(tail.func_flat_map(f), expanded.tail)
56
- }
57
- end
58
-
59
- def map(fn_desc=nil, &blk)
60
- f = Fn.mk_fun_or(fn_desc, &blk)
61
- mapf(f)
62
- end
63
-
64
25
  def nth(n)
65
26
  n.times.reduce(self) {|s,| s.tail}.head
66
27
  end
67
28
 
68
- def mapf(f)
69
- return self.class.empty if empty?
70
- self.class.new(f.(head)) {
71
- tail.mapf(f)
72
- }
73
- end
74
-
75
29
  def split_at(n)
76
30
  [head_stream(n), drop(n)]
77
31
  end
@@ -94,6 +48,11 @@ module ExAequo
94
48
  [take(n), drop(n)]
95
49
  end
96
50
 
51
+ def take_until(fn_desc=nil, more: 0, &blk)
52
+ f = Fn.mk_fun_or(fn_desc, &blk)
53
+ func_take_until(f, more:)
54
+ end
55
+
97
56
  def take_while(&blk)
98
57
  current = self
99
58
  result = []
@@ -2,7 +2,7 @@
2
2
 
3
3
  module ExAequo
4
4
  module Streams
5
- VERSION = '0.1.0'
5
+ VERSION = '0.1.1'
6
6
  end
7
7
  end
8
8
  # SPDX-License-Identifier: AGPL-3.0-or-later
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ex_aequo_streams
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Dober
@@ -52,6 +52,8 @@ files:
52
52
  - lib/ex_aequo/streams/stream.rb
53
53
  - lib/ex_aequo/streams/stream/class_methods.rb
54
54
  - lib/ex_aequo/streams/stream/empty.rb
55
+ - lib/ex_aequo/streams/stream/func_methods.rb
56
+ - lib/ex_aequo/streams/stream/stream_methods.rb
55
57
  - lib/ex_aequo/streams/version.rb
56
58
  homepage: https://codeberg.org/lab419/rb_ex_aequo_streams
57
59
  licenses: