This is another wrong, incomplete implementation of Maybe data type in Ruby. This gist is a full-blown gem. In order to use it, just add the following line to your Gemfile.
gem 'maybe', gist: 'da2aaafdfd71e6ff0ffd'
To my knowledge, all existing gems are too fat and do not provide the ability to configure what values should be treated as Just
and what values are Nothing
. Some treat []
as Nothing
, some treat only nil
as Nothing
, some rely on truthiness (this is the most reasonable choice in my opinion). In my particular use case, I needed to treat obj
as Nothing
iff obj.present?
is true
. Obviously, hard-coding this Railsism into the gem is not an option, so I pass the Nothingness predicate into Maybe data constructor (pardon my French).
User = Struct.new(:twitter_account)
TwitterAccount = Struct.new(:number_of_followers)
def has_many_followers?(user)
Maybe(user)
.fmap(&:twitter_account)
.fmap(&:number_of_followers)
.fmap{ |n| n > 1 }
.from_just { false }
end
has_many_followers?(nil)
# => false
has_many_followers?(User.new(nil))
# => false
has_many_followers?(User.new(TwitterAccount.new(nil)))
# => false
has_many_followers?(User.new(TwitterAccount.new(0)))
# => false
has_many_followers?(User.new(TwitterAccount.new(9001)))
# => true
### Ok, cool, but what if we want to use `present?` or `empty?`?
def greet(username)
Maybe(username, &:present?)
.fmap {|x| "Hello, #{x}!"}
.from_just { 'Nothing to see here, move along' }
end
greet('Simon')
# => "Hello, Simon!"
greet('')
# => "Nothing to see here, move along"
greet(false)
# => "Nothing to see here, move along"
It does indeed.
Maybe(1, &:odd?).fmap(&:succ).fmap(&:pred).from_just{'???'}
# => "???"
Maybe(1, &:odd?).fmap{|x| x.succ.pred}.from_just{'???'}
# => 1
But who cares?
- My own post (in Russian).
- https://www.youtube.com/watch?v=RVHawNWW-JY