rap1ds/ruby-possibly — pull request #8 by rap1ds (2014-08-21 20:07:22+00:00)
Title: 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.

```ruby

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.

```ruby
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:

```ruby
Maybe("I'm not lazy") => #
```

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

```ruby
Maybe { "I'm lazy" } => #:each>>>
```