module Hamster
Constants
- EmptyDeque
The canonical empty `Deque`. Returned by `Deque[]` when invoked with no arguments; also returned by `Deque.empty`. Prefer using this one rather than creating many empty deques using `Deque.new`.
@private
- EmptyHash
The canonical empty `Hash`. Returned by `Hash[]` when invoked with no arguments; also returned by `Hash.empty`. Prefer using this one rather than creating many empty hashes using `Hash.new`.
@private
- EmptySet
The canonical empty `Set`. Returned by `Set[]` when invoked with no arguments; also returned by `Set.empty`. Prefer using this one rather than creating many empty sets using `Set.new`.
@private
- EmptySortedSet
The canonical empty `SortedSet`. Returned by `SortedSet[]` when invoked with no arguments; also returned by `SortedSet.empty`. Prefer using this one rather than creating many empty sorted sets using `SortedSet.new`.
@private
- EmptyTrie
@private
- EmptyVector
The canonical empty `Vector`. Returned by `Vector[]` when invoked with no arguments; also returned by `Vector.empty`. Prefer using this one rather than creating many empty vectors using `Vector.new`.
@private
- VERSION
Current released gem version. Note that master will often have the same value as a release gem but with different code.
Public Class Methods
Turn an `Enumerator` into a `Hamster::List`. The result is a lazy collection where the values are memoized as they are generated.
If your code uses multiple threads, you need to make sure that the returned lazy collection is realized on a single thread only. Otherwise, a `FiberError` will be raised. After the collection is realized, it can be used from other threads as well.
@example
def rg; loop { yield rand(100) }; end Hamster.enumerate(to_enum(:rg)).take(10)
@param enum [Enumerator] The object to iterate over @return [List]
# File lib/hamster/list.rb, line 92 def enumerate(enum) LazyList.new do begin Cons.new(enum.next, enumerate(enum)) rescue StopIteration EmptyList end end end
Create a Hamster immutable data structure with nested Hamster data structure from a nested Ruby object `obj`. This method recursively “walks” the Ruby object, converting Ruby `Hash` to {Hamster::Hash}, Ruby `Array` to {Hamster::Vector}, Ruby `Set` to {Hamster::Set}, and Ruby `SortedSet` to {Hamster::SortedSet}. Other objects are left as-is.
@example
h = Hamster.from({ "a" => [1, 2], "b" => "c" }) # => Hamster::Hash["a" => Hamster::Vector[1, 2], "b" => "c"]
@return [Hash, Vector, Set, SortedSet, Object]
# File lib/hamster/nested.rb, line 24 def from(obj) case obj when ::Hash res = obj.map { |key, value| [from(key), from(value)] } Hamster::Hash.new(res) when Hamster::Hash obj.map { |key, value| [from(key), from(value)] } when ::Struct from(obj.to_h) when ::Array res = obj.map { |element| from(element) } Hamster::Vector.new(res) when ::SortedSet # This clause must go before ::Set clause, since ::SortedSet is a ::Set. res = obj.map { |element| from(element) } Hamster::SortedSet.new(res) when ::Set res = obj.map { |element| from(element) } Hamster::Set.new(res) when Hamster::Vector, Hamster::Set, Hamster::SortedSet obj.map { |element| from(element) } else obj end end
Construct a list of consecutive integers.
@example
Hamster.interval(5,9) # => Hamster::List[5, 6, 7, 8, 9]
@param from [Integer] Start value, inclusive @param to [Integer] End value, inclusive @return [List]
# File lib/hamster/list.rb, line 36 def interval(from, to) return EmptyList if from > to interval_exclusive(from, to.next) end
Create an infinite list where each item is derived from the previous one, using the provided block
@example
Hamster.iterate(0) { |i| i.next }.take(5) # => Hamster::List[0, 1, 2, 3, 4]
@param [Object] item Starting value @yieldparam [Object] previous The previous value @yieldreturn [Object] The next value @return [List]
# File lib/hamster/list.rb, line 74 def iterate(item, &block) LazyList.new { Cons.new(item, iterate(yield(item), &block)) } end
Create an infinite list repeating the same item indefinitely
@example
Hamster.repeat(:chunky).take(4) => Hamster::List[:chunky, :chunky, :chunky, :chunky]
@return [List]
# File lib/hamster/list.rb, line 48 def repeat(item) LazyList.new { Cons.new(item, repeat(item)) } end
Create a list that contains a given item a fixed number of times
@example
Hamster.replicate(3, :hamster) #=> Hamster::List[:hamster, :hamster, :hamster]
@return [List]
# File lib/hamster/list.rb, line 59 def replicate(number, item) repeat(item).take(number) end
Create a lazy, infinite list.
The given block is called as necessary to return successive elements of the list.
@example
Hamster.stream { :hello }.take(3) # => Hamster::List[:hello, :hello, :hello]
@return [List]
# File lib/hamster/list.rb, line 22 def stream(&block) return EmptyList unless block_given? LazyList.new { Cons.new(yield, stream(&block)) } end
Create a Ruby object from Hamster data. This method recursively “walks” the Hamster object, converting {Hamster::Hash} to Ruby `Hash`, {Hamster::Vector} and {Hamster::Deque} to Ruby `Array`, {Hamster::Set} to Ruby `Set`, and {Hamster::SortedSet} to Ruby `SortedSet`. Other objects are left as-is.
@example
h = Hamster.to_ruby(Hamster.from({ "a" => [1, 2], "b" => "c" })) # => { "a" => [1, 2], "b" => "c" }
@return [::Hash, ::Array, ::Set, ::SortedSet, Object]
# File lib/hamster/nested.rb, line 61 def to_ruby(obj) case obj when Hamster::Hash, ::Hash obj.each_with_object({}) { |keyval, hash| hash[to_ruby(keyval[0])] = to_ruby(keyval[1]) } when Hamster::Vector, ::Array obj.each_with_object([]) { |element, arr| arr << to_ruby(element) } when Hamster::Set, ::Set obj.each_with_object(::Set.new) { |element, set| set << to_ruby(element) } when Hamster::SortedSet, ::SortedSet obj.each_with_object(::SortedSet.new) { |element, set| set << to_ruby(element) } when Hamster::Deque obj.to_a.tap { |arr| arr.map! { |element| to_ruby(element) }} else obj end end
Private Class Methods
# File lib/hamster/list.rb, line 104 def interval_exclusive(from, to) return EmptyList if from == to LazyList.new { Cons.new(from, interval_exclusive(from.next, to)) } end