Module: Immutable::Headable

Includes:
Enumerable, Foldable
Included in:
Consable, Queue
Defined in:
lib/immutable/headable.rb

Instance Method Summary collapse

Methods included from Foldable

#length, #product, #sum

Instance Method Details

#==(x) ⇒ true, false

Returns whether self equals to x.

Parameters:

  • x (Object)

    the object to compare.

Returns:

  • (true, false)

    true if self equals to x; otherwise, false.



80
81
82
83
84
85
86
87
88
89
90
# File 'lib/immutable/headable.rb', line 80

def ==(x)
  if !x.is_a?(self.class)
    false
  else
    if empty?
      x.empty?
    else
      !x.empty? && head == x.head && tail == x.tail
    end
  end
end

#[](n) ⇒ Object Also known as: at

Returns the nth element of self. If n is out of range, nil is returned.

Parameters:

  • n (Integer, #to_int)

Returns:

  • (Object)

    the nth element.

Raises:

  • (TypeError)


226
227
228
229
230
231
232
233
234
235
236
237
# File 'lib/immutable/headable.rb', line 226

def [](n)
  raise TypeError unless n.respond_to?(:to_int)
  int = n.to_int

  if int < 0 || empty?
    nil
  elsif int == 0
    head
  else
    tail[int - 1]
  end
end

#each {|element| ... } ⇒ Enumerator

Calls block once for each element in self.

Yields:

  • (element)

Yield Returns:

  • (self)

Returns:

  • (Enumerator)


113
114
115
116
117
118
119
120
121
122
# File 'lib/immutable/headable.rb', line 113

def each(&block)
  return to_enum unless block_given?
  
  unless empty?
    yield(head)
    tail.each(&block)
  end
  
  self
end

#each_index {|index| ... } ⇒ Enumerator

Calls block once for each index in self.

Yields:

Yield Parameters:

  • index (Integer)

Yield Returns:

  • (self)

Returns:

  • (Enumerator)


129
130
131
132
133
# File 'lib/immutable/headable.rb', line 129

def each_index
  return to_enum(__callee__) unless block_given?
  
  each_with_index{ |_, idx| yield(idx) }
end

#empty?true, false

Returns whether self is empty. A class including Immutable::Headable must implement this method.

Returns:

  • (true, false)

    true if self is empty; otherwise, false.

Raises:

  • (NotImplementedError)


50
51
52
# File 'lib/immutable/headable.rb', line 50

def empty?
  raise NotImplementedError
end

#eql?(x) ⇒ Boolean

Returns:

  • (Boolean)


92
93
94
95
96
97
98
99
100
101
102
# File 'lib/immutable/headable.rb', line 92

def eql?(x)
  if !x.is_a?(self.class)
    false
  else
    if empty?
      x.empty?
    else
      !x.empty? && head.eql?(x.head) && tail.eql?(x.tail)
    end
  end
end

#fetch(n) ⇒ Object #fetch(n, ifnone) ⇒ Object #fetch(n) {|n| ... } ⇒ Object

Returns the nth element of self. If n is out of range, IndexError returned.

Overloads:

  • #fetch(n) ⇒ Object

    Returns the nth element.

    Parameters:

    • n (Integer, #to_int)

    Returns:

    • (Object)

      the nth element.

    Raises:

    • (IndexError)

      if n is out of rage

  • #fetch(n, ifnone) ⇒ Object

    Returns ifnone.

    Parameters:

    • n (Integer, #to_int)

    Returns:

    • ifnone

  • #fetch(n) {|n| ... } ⇒ Object

    Parameters:

    • n (Integer, #to_int)

    Yields:

    • (n)

    Yield Parameters:

    • n (Integer, #to_int)

Raises:

  • (TypeError)


255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
# File 'lib/immutable/headable.rb', line 255

def fetch(*args)
  alen = args.length
  n, ifnone = *args
  
  unless (1..2).cover?(alen)
    raise ArgumentError, "wrong number of arguments (#{alen} for 1..2)"
  end

  raise TypeError unless n.respond_to?(:to_int)
  int = n.to_int

  return at(int) if int >= 0 && int < length

  if block_given?
    if alen == 2
      warn "#{__LINE__}:warning: block supersedes default value argument"
    end

    yield n
  else
    if alen == 2
      ifnone
    else
      raise IndexError, "index #{int} outside of list bounds"
    end
  end
end

#find(ifnone = nil) {|element| ... } ⇒ Enumerator Also known as: detect

Returns the first element in self for which the given block evaluates to true. If such an element is not found, it returns nil.

Parameters:

  • ifnone (#call, nil) (defaults to: nil)

Yields:

  • (element)

Yield Returns:

  • (Object)

    the found element.

Returns:

  • (Enumerator)


201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
# File 'lib/immutable/headable.rb', line 201

def find(ifnone=nil, &block)
  return to_enum(__callee__, ifnone) unless block_given?

  if empty?
    if ifnone.nil?
      nil
    else
      ifnone.call
    end
  else
    if yield(head)
      head
    else
      tail.find(ifnone, &block)
    end
  end
end

#firstObject

Same as #head. This method just calls #head.

Returns:

  • (Object)

    the first element of self.



26
27
28
# File 'lib/immutable/headable.rb', line 26

def first
  head
end

#foldl(e, &block) ⇒ Object

Reduces self using block from left to right. e is used as the starting value. For example:

List[1, 2, 3].foldl(9) { |x, y| x - y } #=> ((9 - 1) - 2) - 3 = 3

Parameters:

  • e (Object)

    the start value.

Returns:

  • (Object)

    the reduced value.



173
174
175
176
177
178
179
# File 'lib/immutable/headable.rb', line 173

def foldl(e, &block)
  if empty?
    e
  else
    tail.foldl(yield(e, head), &block)
  end
end

#foldl1(&block) ⇒ Object

Reduces self using block from left to right. If self is empty, Immutable::EmptyError is raised.

Returns:

  • (Object)

    the reduced value.



185
186
187
188
189
190
191
# File 'lib/immutable/headable.rb', line 185

def foldl1(&block)
  if empty?
    raise EmptyError
  else
    tail.foldl(head, &block)
  end
end

#foldr(e, &block) ⇒ Object

Reduces self using block from right to left. e is used as the starting value. For example:

List[1, 2, 3].foldr(9) { |x, y| x - y } #=> 1 - (2 - (3 - 9)) = -7

Parameters:

  • e (Object)

    the start value.

Returns:

  • (Object)

    the reduced value.



142
143
144
145
146
147
148
# File 'lib/immutable/headable.rb', line 142

def foldr(e, &block)
  if empty?
    e
  else
    yield(head, tail.foldr(e, &block))
  end
end

#foldr1(&block) ⇒ Object

Reduces self using block from right to left. If self is empty, Immutable::EmptyError is raised.

Returns:

  • (Object)

    the reduced value.



154
155
156
157
158
159
160
161
162
163
164
# File 'lib/immutable/headable.rb', line 154

def foldr1(&block)
  if empty?
    raise EmptyError
  else
    if tail.empty?
      head
    else
      yield(head, tail.foldr1(&block))
    end
  end
end

#hashInteger

Returns:

  • (Integer)


105
106
107
# File 'lib/immutable/headable.rb', line 105

def hash
  to_a.hash
end

#headObject

Returns the first element of self. If self is empty, Immutable::EmptyError is raised. A class including Immutable::Headable must implement this method.

Returns:

  • (Object)

    the first element of self.

Raises:

  • (NotImplementedError)


19
20
21
# File 'lib/immutable/headable.rb', line 19

def head
  raise NotImplementedError
end

#index(val) ⇒ Integer? #indexEnumerator #index({}) ⇒ Object

Overloads:

  • #index(val) ⇒ Integer?

    Returns index.

    Returns:

    • (Integer, nil)

      index

  • #indexEnumerator

    Returns:

    • (Enumerator)
  • #index({}) ⇒ Object

    Yield Returns:

    • (Integer, nil)

      index

Raises:

  • (ArgumentError)


289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
# File 'lib/immutable/headable.rb', line 289

def index(*args)
  alen = args.length
  val = args.first

  raise ArgumentError unless (0..1).cover?(alen)
  return to_enum(__callee__) if !block_given? && alen == 0

  if alen == 1
    if block_given?
      warn "#{__LINE__}:warning: given block not used"
    end

    each_with_index { |e, idx|
      return idx if e == val
    }
  else
    if block_given?
      each_with_index { |e, idx|
        return idx if yield(e)
      }
    end
  end

  nil
end

#inspectString Also known as: to_s

Returns a string containing a human-readable representation of self.

Returns:

  • (String)

    a string representation of self.



64
65
66
67
68
69
70
71
# File 'lib/immutable/headable.rb', line 64

def inspect
  if empty?
    class_name + "[]"
  else
    class_name + "[" + head.inspect +
      tail.foldl("") {|x, y| x + ", " + y.inspect } + "]"
  end
end

#null?true, false

Same as #empty?. This method just calls #empty?.

Returns:

  • (true, false)

    true if self is empty; otherwise, false.



57
58
59
# File 'lib/immutable/headable.rb', line 57

def null?
  empty?
end

#rindex(val) ⇒ Integer? #rindexEnumerator #rindex({}) ⇒ Object

Overloads:

  • #rindex(val) ⇒ Integer?

    Returns index.

    Returns:

    • (Integer, nil)

      index

  • #rindexEnumerator

    Returns:

    • (Enumerator)
  • #rindex({}) ⇒ Object

    Yield Returns:

    • (Integer, nil)

      index

Raises:

  • (ArgumentError)


321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
# File 'lib/immutable/headable.rb', line 321

def rindex(*args)
  alen = args.length
  val = args.first

  raise ArgumentError unless (0..1).cover?(alen)
  return to_enum(__callee__) if !block_given? && alen == 0

  if alen == 1
    if block_given?
      warn "#{__LINE__}:warning: given block not used"
    end

    reverse_each.with_index { |e, idx|
      return length - (idx + 1) if e == val
    }
  else
    if block_given?
      reverse_each.with_index { |e, idx|
        return length - (idx + 1) if yield(e)
      }
    end
  end

  nil
end

#shiftHeadable

Same as #tail. This method just calls #tail.

Returns:

  • (Headable)

    the elements after the head of self.



42
43
44
# File 'lib/immutable/headable.rb', line 42

def shift
  tail
end

#tailHeadable

Returns the elements after the head of self. If self is empty, Immutable::EmptyError is raised. A class including Immutable::Headable must implement this method.

Returns:

  • (Headable)

    the elements after the head of self.

Raises:

  • (NotImplementedError)


35
36
37
# File 'lib/immutable/headable.rb', line 35

def tail
  raise NotImplementedError
end

#to_listList

Converts self to a list.

Returns:

  • (List)

    a list.



350
351
352
# File 'lib/immutable/headable.rb', line 350

def to_list
  foldr(List[]) { |x, xs| Cons[x, xs] }
end