Trouble understanding dry-monads `#or`


#1

Hi!
About dry-monads, consider this:

require 'dry-monads'
include Dry::Monads::Either::Mixin

def call
  find_by_x
    .or(find_by_y)
    .or(create_new)
end

def find_by_x
  if @condition
    Right('x')
  else
    Left(nil)
  end
end

def find_by_y
  if @condition
    Right('y')
  else
    Left(nil)
  end
end

def create_new
  p "create_new called"
  Right('z')
end

# use case 1:

@condition = false
call
"create_new called"
=> Right("z")

# use case 2:

@condition = true
call
"create_new called"
=> Right("x")

The results in both use cases are as expected.

What confuses me is that in both cases the #create_new method was called.
In docs there is a description that #or works opposite to #bind. Bind skips execution when Left occurs. Shouldn’t #or skip execution when Right occurs? Is is a desired behaviour or a bug? Can You help me understand that?


#2

Ok got it. I should have used blocks.

def call
  find_by_x
    .or { find_by_y }
    .or { create_new }
end