Skip to content

Instantly share code, notes, and snippets.

@cutalion
Last active February 7, 2020 12:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cutalion/d053c655d1b9b4c1dacdd867799ec76c to your computer and use it in GitHub Desktop.
Save cutalion/d053c655d1b9b4c1dacdd867799ec76c to your computer and use it in GitHub Desktop.
monads vs exceptions
require 'pry'
# A
# |- B
# | |- D
# |
# |- C
AppError = Class.new(StandardError)
Error1 = Class.new(AppError)
Error2 = Class.new(AppError)
Error3 = Class.new(AppError)
Error4 = Class.new(AppError)
class A
def self.call
B.call
C.call
:a
end
end
class B
def self.call
D.call
# maybe raise Error1
:b
end
end
class C
def self.call
# maybe raise Error2
:c
end
end
class D
def self.call
raise [Error3, Error4].sample, :d
end
end
begin
puts A.call
rescue Error3 => e
puts "Error 3: #{e.message}"
rescue Error4 => e
puts "Error 4: #{e.message}"
rescue AppError => e
puts "App Error: #{e.message}"
end
require 'dry/monads'
require 'dry/monads/do'
require 'pry'
# A
# |- B
# | |- D
# |
# |- C
include Dry::Monads[:result]
class A
extend Dry::Monads[:result, :do]
def self.call
yield B.call
yield C.call
#
Success(:a)
end
end
class B
extend Dry::Monads[:result, :do]
def self.call
yield D.call
# maybe Failure(:b)
Success(:b)
end
end
class C
extend Dry::Monads[:result, :do]
def self.call
# maybe Failure(:c)
Success(:c)
end
end
class D
extend Dry::Monads[:result, :do]
def self.call
[Failure(:d1), Failure(:d2)].sample
end
end
res = A.call
case res
when Success
puts res
when Failure(:d1)
puts 'Error: d1'
when Failure(:d2)
puts 'Error: d2'
when Failure
puts "App Error: #{res.failure}"
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment