Skip to content

Instantly share code, notes, and snippets.

@alexandru-calinoiu
Created November 6, 2016 03:10
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 alexandru-calinoiu/55501c1b3272919464bd28367de114a6 to your computer and use it in GitHub Desktop.
Save alexandru-calinoiu/55501c1b3272919464bd28367de114a6 to your computer and use it in GitHub Desktop.
Play around with dry monads.
require 'dry-monads'
class Address
attr_reader :street
def initialize(street = nil)
@street = street
end
end
class User
attr_reader :address
def initialize(address = nil)
@address = address
end
end
M = Dry::Monads
user = User.new(Address.new('some address'))
maybe_user = M.Maybe(user).bind do |u|
M.Maybe(u.address).bind do |a|
M.Maybe(a.street)
end
end
p maybe_user
# pass a proc
add_two = -> (x) { M.Maybe(x + 2) }
p M.Maybe(38).bind(add_two).bind(add_two)
p M.Maybe(nil).bind(add_two)
p M.Maybe(user).fmap(&:address).fmap(&:street)
p M.Some(5).fmap(&:succ).value
p M.None.fmap(&:succ).value
p M.Some(32).bind(add_two).bind(add_two).or(M.Some(1))
p M.None.bind(add_two).bind(add_two).or(M.Some(1))
class EitherCalculator
include Dry::Monads::Either::Mixin
attr_accessor :input
def calculate
i = Integer(input)
Right(i).bind do |value|
if value > 1
Right(value + 3)
else
Left('Value is less then 1')
end
end.bind do |value|
if value % 2 == 0
Right(value * 2)
else
Left('Value was not even')
end
end
end
end
calculator = EitherCalculator.new
calculator.input = 3
p calculator.calculate
p calculator.calculate.value
calculator.input = 0
p calculator.calculate
p calculator.calculate.value
calculator.input = 2
p calculator.calculate
p calculator.calculate.value
foo = 1
bar = 2
result = if foo > bar
M.Right(10)
else
M.Left('Wrong values')
end.fmap { |x| x * 2 }
p result
p result.left?
p result.right?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment