Class: Functional::Tuple

Inherits:
Object
  • Object
show all
Defined in:
lib/functional/tuple.rb

Overview

Note:

The current implementation uses simple Ruby arrays. This is likely to be very inefficient for all but the smallest tuples. The more items the tuple contains, the less efficient it will become. A future version will use a fast, immutable, persistent data structure such as a finger tree or a trie.

A tuple is a pure functional data strcture that is similar to an array but is immutable and of fixed length. Tuples support many of the same operations as array/list/vector.

Instance Method Summary collapse

Constructor Details

#initialize(data = []) ⇒ Tuple

Create a new tuple with the given data items in the given order.

Parameters:

  • data (Array) (defaults to: [])

    the data items to insert into the new tuple

Raises:

  • (ArgumentError)

    if data is not an array or does not implement to_a

Since:

  • 1.1.0


30
31
32
33
34
# File 'lib/functional/tuple.rb', line 30

def initialize(data = [])
  raise ArgumentError.new('data is not an array') unless data.respond_to?(:to_a)
  @data = data.to_a.dup.freeze
  self.freeze
end

Instance Method Details

#at(index) ⇒ Object Also known as: nth, []

Retrieve the item at the given index. Indices begin at zero and increment up, just like Ruby arrays. Negative indicies begin at -1, which represents the last item in the tuple, and decrement toward the first item. If the given index is out of range then nil is returned.

Parameters:

  • index (Fixnum)

    the index of the item to be retrieved

Returns:

  • (Object)

    the item at the given index or nil when index is out of bounds

Since:

  • 1.1.0


43
44
45
# File 'lib/functional/tuple.rb', line 43

def at(index)
  @data[index]
end

#concat(other) ⇒ Functional::Tuple Also known as: +

Returns a new tuple built by concatenating the two tuples together to produce a third tuple.

Parameters:

  • other (Array)

    the tuple or array-like object (responds to to_a) to operate on

Returns:

Since:

  • 1.1.0


98
99
100
# File 'lib/functional/tuple.rb', line 98

def concat(other)
  Tuple.new(@data + other.to_a)
end

#diff(other) ⇒ Functional::Tuple Also known as: -

Returns a new tuple that is a copy of the original tuple, removing any items that also appear in other. The order is preserved from the original tuple.

Parameters:

  • other (Array)

    the tuple or array-like object (responds to to_a) to operate on

Returns:

Since:

  • 1.1.0


107
108
109
# File 'lib/functional/tuple.rb', line 107

def diff(other)
  Tuple.new(@data - other.to_a)
end

#each {|item| ... } ⇒ Enumerable

Calls the given block once for each element in self, passing that element as a parameter. An Enumerator is returned if no block is given.

Yield Parameters:

  • item (Object)

    the current item

Returns:

  • (Enumerable)

    when no block is given

Since:

  • 1.1.0


137
138
139
140
141
142
# File 'lib/functional/tuple.rb', line 137

def each
  return enum_for(:each) unless block_given?
  @data.each do |item|
    yield(item)
  end
end

#each_with_index {|item, index| ... } ⇒ Enumerable

Calls the given block once for each element in self, passing that element and the current index as parameters. An Enumerator is returned if no block is given.

Yield Parameters:

  • item (Object)

    the current item

  • index (Fixnum)

    the index of the current item

Returns:

  • (Enumerable)

    when no block is given

Since:

  • 1.1.0


150
151
152
153
154
155
# File 'lib/functional/tuple.rb', line 150

def each_with_index
  return enum_for(:each_with_index) unless block_given?
  @data.each_with_index do |item, index|
    yield(item, index)
  end
end

#empty?Boolean

Returns true if self contains no items.

Returns:

  • (Boolean)

    true when empty else false

Since:

  • 1.1.0


194
195
196
# File 'lib/functional/tuple.rb', line 194

def empty?
  @data.empty?
end

#eql?(other) ⇒ Boolean Also known as: ==

Compares this object and other for equality. A tuple is eql? to other when other is a tuple or an array-like object (any object that responds to to_a) and the two objects have identical values in the same foxed order.

Parameters:

  • other (Object)

    the other tuple to compare for equality

Returns:

  • (Boolean)

    true when equal else false

Since:

  • 1.1.0


186
187
188
# File 'lib/functional/tuple.rb', line 186

def eql?(other)
  @data == other.to_a
end

#fetch(index, default) ⇒ Object

Retrieve the item at the given index or return the given default value if the index is out of bounds. The behavior of indicies follows the rules for the at method.

Parameters:

  • index (Fixnum)

    the index of the item to be retrieved

  • default (Object)

    the value to return when given an out of bounds index

Returns:

  • (Object)

    the item at the given index or default when index is out of bounds

See Also:

Since:

  • 1.1.0


58
59
60
61
62
63
64
# File 'lib/functional/tuple.rb', line 58

def fetch(index, default)
  if index >= length || -index > length
    default
  else
    at(index)
  end
end

#firstObject Also known as: head

Returns the first element of the tuple or nil when empty.

Returns:

  • (Object)

    the first element or nil

Since:

  • 1.1.0


201
202
203
# File 'lib/functional/tuple.rb', line 201

def first
  @data.first
end

#intersect(other) ⇒ Functional::Tuple Also known as: &

Returns a new tuple containing elements common to the two tuples, excluding any duplicates. The order is preserved from the original tuple.

Parameters:

  • other (Array)

    the tuple or array-like object (responds to to_a) to operate on

Returns:

Since:

  • 1.1.0


80
81
82
# File 'lib/functional/tuple.rb', line 80

def intersect(other)
  Tuple.new(@data & other.to_a)
end

#lengthFixnum Also known as: size

The number of items in the tuple.

Returns:

  • (Fixnum)

    the number of items in the tuple

Since:

  • 1.1.0


69
70
71
# File 'lib/functional/tuple.rb', line 69

def length
  @data.length
end

#repeat(multiple) ⇒ Functional::Tuple Also known as: *

Returns a new tuple built by concatenating the given number of copies of self. Returns an empty tuple when the multiple is zero.

Parameters:

  • multiple (Fixnum)

    the number of times to concatenate self

Returns:

Raises:

  • (ArgumentError)

    when multiple is a negative number

Since:

  • 1.1.0


118
119
120
121
122
# File 'lib/functional/tuple.rb', line 118

def repeat(multiple)
  multiple = multiple.to_i
  raise ArgumentError.new('negative argument') if multiple < 0
  Tuple.new(@data * multiple)
end

#restFunctional::Tuple Also known as: tail

Returns a tuple containing all the items in self after the first item. Returns an empty tuple when empty or there is only one item.

Returns:

Since:

  • 1.1.0


210
211
212
213
214
215
216
# File 'lib/functional/tuple.rb', line 210

def rest
  if @data.length <= 1
    Tuple.new
  else
    Tuple.new(@data.slice(1..@data.length-1))
  end
end

#sequence {|head, tail| ... } ⇒ Enumerable

Calls the given block once for each element in self, passing that element and a tuple with all the remaining items in the tuple. When the last item is reached ab empty tuple is passed as the second parameter. This is the classic functional programming head|tail list processing idiom. An Enumerator is returned if no block is given.

Yield Parameters:

  • head (Object)

    the current item for this iteration

  • tail (Tuple)

    the remaining items (tail) or an empty tuple when processing the last item

Returns:

  • (Enumerable)

    when no block is given

Since:

  • 1.1.0


167
168
169
170
171
172
173
174
175
176
177
# File 'lib/functional/tuple.rb', line 167

def sequence
  return enum_for(:sequence) unless block_given?
  @data.length.times do |index|
    last = @data.length - 1
    if index == last
      yield(@data[index], Tuple.new)
    else
      yield(@data[index], Tuple.new(@data.slice(index+1..last)))
    end
  end
end

#to_aArray Also known as: to_ary

Create a standard Ruby mutable array containing the tuple items in the same order.

Returns:

  • (Array)

    the new array created from the tuple

Since:

  • 1.1.0


223
224
225
# File 'lib/functional/tuple.rb', line 223

def to_a
  @data.dup
end

#union(other) ⇒ Functional::Tuple Also known as: |

Returns a new tuple by joining self with other, excluding any duplicates and preserving the order from the original tuple.

Parameters:

  • other (Array)

    the tuple or array-like object (responds to to_a) to operate on

Returns:

Since:

  • 1.1.0


89
90
91
# File 'lib/functional/tuple.rb', line 89

def union(other)
  Tuple.new(@data | other.to_a)
end

#uniqFunctional::Tuple

Returns a new tuple by removing duplicate values in self.

Returns:

Since:

  • 1.1.0


128
129
130
# File 'lib/functional/tuple.rb', line 128

def uniq
  Tuple.new(@data.uniq)
end