ruby-possibly
ruby-possibly copied to clipboard
What if Maybe was lazy?
This is an opt-in implementation for laziness. By default Maybes are not lazy, but if you call lazy or initialize Maybe with a block, it becomes lazy.
From README:
Laziness
Ruby 2.0 introduced lazy enumerables. By calling lazy on any enumerable, you get the lazy version of it. Same goes with Maybe.
called = false
m = Maybe(2).lazy.map do |value|
called = true;
value * value;
end
puts called # => false
puts m.get # => 4 # Map is called now
puts called # => true
You can also initialize Maybe lazily by giving it a block.
initialization_block_called = false
map_called = false
m = Maybe do
initialization_block_called = true
do_some_expensive_calculation # returns 1234567890
end.map do |value|
map_called = true;
"the value of expensive calculation: #{value}";
end
puts initialization_block_called # => false
puts map_called # => false
puts m.get # => "the value of expensive calculation: 1234567890 # Map is called now
puts initialization_block_called # => true
puts map_called # => true
Note that if you initialize a maybe non-lazily and inspect it, you see from the class that it is a Some:
Maybe("I'm not lazy") => #<Some:0x007ff7ac8697b8 @value=2>
However, if you initialize Maybe lazily, we do not know the type before the lazy block is evaluated. Thus, you see a different output when printing the value
Maybe { "I'm lazy" } => #<Maybe:0x0000010107a600 @lazy=#<Enumerator::Lazy: #<Enumerator: #<Enumerator::Generator:0x0000010107a768>:each>>>