Last active
August 4, 2021 16:05
-
-
Save ismasan/69ac79e352b4dd40f8cc0c48cc847f30 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# https://vimeo.com/113707214 | |
class Result | |
attr_reader :value | |
def initialize(v) | |
@value = v | |
end | |
class << self | |
def success(v) | |
Success.new(v) | |
end | |
def failure(v, err = nil) | |
Failure.new(v, err) | |
end | |
def wrap(v) | |
v.is_a?(Result) ? v : success(v) | |
end | |
end | |
class Success < self | |
end | |
class Failure < self | |
attr_reader :error | |
def initialize(value, error = nil) | |
super value | |
@error = error | |
end | |
end | |
end | |
# Turn a "single track" function (a function that only takes a successful result as an argument, ie. the happy path) | |
# into a two-track function, ie. a function that, if given a failure as argument, it just forwards it along to the end of the pipeline. | |
# So that "bound" functions can be composed together into a two-track pipeline | |
# | |
# let SingleTrackFn = fn(Success) -> Success | Failure | |
# let bind = fn(SingleTrackFn) -> fn(Success | Failure) -> Success | Failure | |
def bind(func) | |
proc do |r| | |
r = Result.wrap(r) | |
r.is_a?(Result::Failure) ? r : func.call(r) | |
end | |
end | |
validate_email = proc do |r| | |
r.value[:email] =~ /@/ ? r : Result.failure(r.value, 'not an email!') | |
end | |
validate_name = proc do |r| | |
r.value[:name].size >= 10 ? r : Result.failure(r.value, 'name too short') | |
end | |
pipeline = bind(validate_email) >> bind(validate_name) | |
p pipeline.call({ name: 'Ismael Celis', email: '[email protected]' }) # Result::Success value={name: 'Ismael' ...etc } | |
p pipeline.call({ name: 'Isma', email: '[email protected]' }) # Result::Failure error='name too short' value={name: 'Ismael' ...etc } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment