Last active
May 27, 2017 13:32
-
-
Save fmnoise/536ee4a9ca4687fb0d324d3c1899097c to your computer and use it in GitHub Desktop.
Simple Ruby implementations of some monads (just for fun)
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
module Monads | |
class Box | |
def self.[](value) | |
self.new(value) | |
end | |
def initialize(value) | |
@value = value | |
end | |
def >> | |
self.class.new yield @value | |
end | |
def <= | |
block_given? ? yield(@value) : @value | |
end | |
end | |
class Maybe < Box | |
def >> | |
self.class.new(@value.nil? ? nil : block_given? ? yield(@value) : @value) | |
end | |
def <= | |
@value.nil? ? nil : block_given? ? yield(@value) : @value | |
end | |
end | |
class Try | |
def self.to | |
Right[yield] | |
rescue StandardError => e | |
Left[e] | |
end | |
class Right < Box | |
def >> | |
self.class[yield @value] | |
rescue StandardError => e | |
Left[e] | |
end | |
def <= | |
yield nil, @value | |
end | |
end | |
class Left < Box | |
def >> | |
self | |
end | |
def <= | |
yield @value, nil | |
end | |
end | |
end | |
end |
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
############################### | |
# Box | |
#----------before-------------- | |
def filtered_sales | |
filter_by_tags \ | |
filter_by_category \ | |
filter_by_client \ | |
filter_by_seller \ | |
sales_by_dates | |
end | |
#----------after-------------- | |
def filtered_sales | |
Monads::Box[sales_by_dates]. | |
>> {|v| filter_by_seller v}. | |
>> {|v| filter_by_client v}. | |
>> {|v| filter_by_category v}. | |
<= {|v| filter_by_tags v} | |
end | |
############################### | |
############################### | |
# Maybe | |
#----------before-------------- | |
def email_service user_id | |
if user = User.find_by_id(user_id) | |
if email = user.email | |
if service = email.split('@').last | |
service.upcase | |
end | |
end | |
end | |
end | |
#----------after-------------- | |
def email_service user_id | |
Monads::Maybe[user_id]. | |
>> {|v| User.find_by_id(v)}. | |
>> (&:email). | |
>> {|v| v.split '@'}. | |
>> (&:last). | |
<= (&:upcase) | |
end | |
############################### | |
# Try aka Either | |
#----------before-------------- | |
def get_service_port default_port | |
begin | |
file = File.open('config.json') | |
config = JSON.parse(file) | |
config['port'] || default_port | |
rescue StandardError => e | |
default_port | |
end | |
end | |
def get_service_port default_port | |
Monads::Try.to { File.open('config.json') }. | |
>> {|v| JSON.parse v }. | |
>> {|v| v['port'] || default_port }. | |
<= {|err,v| err ? default_port : v } | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment