Class: Fear::For

Inherits:
Object
  • Object
show all
Defined in:
lib/fear/for.rb,
lib/fear/for/evaluation_context.rb

Overview

This class provides syntactic sugar for composition of multiple monadic operations. It supports two such operations - flat_map and map. Any class providing them is supported by For.

For(a: Some(2), b: Some(3)) { a * b } #=> Some(6)

If one of operands is None, the result is None

For(a: Some(2), b: None()) { a * b } #=> None()
For(a: None(), b: Some(2)) { a * b } #=> None()

Lets look at first example:

For(a: Some(2), b: Some(3)) { a * b }

would be translated to:

Some(2).flat_map do |a|
  Some(3).map do |b|
    a * b
  end
end

It works with arrays as well

For(a: [1, 2], b: [2, 3], c: [3, 4]) { a * b * c }
  #=> [6, 8, 9, 12, 12, 16, 18, 24]

would be translated to:

[1, 2].flat_map do |a|
  [2, 3].flat_map do |b|
    [3, 4].map do |c|
      a * b * c
    end
  end
end

If you pass lambda as a variable value, it would be evaluated only on demand.

For(a: -> { None() }, b: -> { fail 'kaboom' } ) { a * b }
  #=> None()

It does not fail since ‘b` is not evaluated. You can mix and match lambdas and variables.

For(a: -> None(), b: -> { fail 'kaboom' } ) { a * b }
  #=> None()

Defined Under Namespace

Modules: Mixin

Instance Method Summary collapse

Constructor Details

#initialize(outer_context, **variables) ⇒ For

Returns a new instance of For.

Parameters:

  • variables (Hash{Symbol => any})


61
62
63
64
# File 'lib/fear/for.rb', line 61

def initialize(outer_context, **variables)
  @variables = variables
  @evaluation_context = EvaluationContext.new(outer_context)
end

Instance Method Details

#call(&block) ⇒ Object



66
67
68
69
# File 'lib/fear/for.rb', line 66

def call(&block)
  variable_name_and_monad, *tail = *variables
  execute(*variable_name_and_monad, tail, &block)
end