Skip to content

Instantly share code, notes, and snippets.

@urmastalimaa
Last active February 18, 2016 08:58
Show Gist options
  • Save urmastalimaa/fa1b2cc29c3452278b28 to your computer and use it in GitHub Desktop.
Save urmastalimaa/fa1b2cc29c3452278b28 to your computer and use it in GitHub Desktop.
monadic_tracktor
require 'rubygems'
require 'deterministic'
include Deterministic::Prelude::Result
Operator = Class.new
Visitor = Class.new
fetch_operator = Proc.new {|request|
Operator.new
}
fetch_visitor = Proc.new {|request|
Success(Visitor.new)
# Failure("No such visitor")
}
start_engagement = Proc.new {|request|
puts "Starting engagement"
Success(request)
# Failure("bad engagement")
}
render_response = Proc.new {|request|
operator = request.fetch(:operator)
visitor = request.fetch(:visitor)
{message: "#{operator.class.name} ##{operator.object_id} started engagement with #{visitor.class.name} ##{visitor.object_id}"}
}
store_operator = Proc.new {|request|
puts "Storing operator"
}
notify_participants = Proc.new {|request|
puts "Notifying participants"
}
def Merge(key, fn)
Proc.new {|request|
fn.call(request)
.map {|result| Success(request.merge(key => result)) }
}
end
def OnSuccess(block)
Proc.new {|request|
block.call(request)
Success(request)
}
end
def Pure(block)
Proc.new {|request|
Success(block.call(request))
}
end
def Chain(*steps)
Proc.new {|request|
steps.reduce(Success(request)) {|acc, step| acc >> step }
}
end
start_engagement = Chain(
Merge(:operator, Pure(fetch_operator)),
Merge(:visitor, fetch_visitor),
start_engagement,
OnSuccess(notify_participants),
OnSuccess(store_operator),
Pure(render_response)
)
tracktor = Proc.new {
# Very similar to current substation solution
request = {operator_id: 5, visitor_id: 6}
response = start_engagement.call(request)
puts response.inspect
}
tracktor.call
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment