-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #4 from rap1ds/threequals
Implement threequals so that Maybe can be used in case expressions
- Loading branch information
Showing
3 changed files
with
193 additions
and
93 deletions.
There are no files selected for viewing
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,113 +1,111 @@ | ||
module Maybe | ||
# Parent class for Maybe::Some and Maybe::None. You should never | ||
# instantiate this class. | ||
class Maybe | ||
([:each] + Enumerable.instance_methods).each do |enumerable_method| | ||
define_method(enumerable_method) do |*args, &block| | ||
res = __enumerable_value.send(enumerable_method, *args, &block) | ||
res.respond_to?(:each) ? Maybe(res.first) : res | ||
end | ||
class Maybe | ||
([:each] + Enumerable.instance_methods).each do |enumerable_method| | ||
define_method(enumerable_method) do |*args, &block| | ||
res = __enumerable_value.send(enumerable_method, *args, &block) | ||
res.respond_to?(:each) ? Maybe(res.first) : res | ||
end | ||
end | ||
|
||
def to_ary | ||
__enumerable_value | ||
end | ||
alias_method :to_a, :to_ary | ||
def to_ary | ||
__enumerable_value | ||
end | ||
alias_method :to_a, :to_ary | ||
|
||
def ==(other) | ||
other.class == self.class | ||
end | ||
alias_method :eql?, :== | ||
def ==(other) | ||
other.class == self.class | ||
end | ||
alias_method :eql?, :== | ||
end | ||
|
||
# Represents a non-empty value | ||
class Some < Maybe | ||
def initialize(value) | ||
@value = value | ||
end | ||
# Represents a non-empty value | ||
class Some < Maybe | ||
def initialize(value) | ||
@value = value | ||
end | ||
|
||
def get | ||
@value | ||
end | ||
def get | ||
@value | ||
end | ||
|
||
def or_else(*) | ||
@value | ||
end | ||
def or_else(*) | ||
@value | ||
end | ||
|
||
# rubocop:disable PredicateName | ||
def is_some? | ||
true | ||
end | ||
# rubocop:disable PredicateName | ||
def is_some? | ||
true | ||
end | ||
|
||
def is_none? | ||
false | ||
end | ||
# rubocop:enable PredicateName | ||
def is_none? | ||
false | ||
end | ||
# rubocop:enable PredicateName | ||
|
||
def ==(other) | ||
super && get == other.get | ||
end | ||
alias_method :eql?, :== | ||
def ==(other) | ||
super && get == other.get | ||
end | ||
alias_method :eql?, :== | ||
|
||
def method_missing(method_sym, *args, &block) | ||
map { |value| value.send(method_sym, *args, &block) } | ||
end | ||
def ===(other) | ||
other && other.class == self.class && @value === other.get | ||
end | ||
|
||
private | ||
def method_missing(method_sym, *args, &block) | ||
map { |value| value.send(method_sym, *args, &block) } | ||
end | ||
|
||
def __enumerable_value | ||
[@value] | ||
end | ||
private | ||
|
||
def __enumerable_value | ||
[@value] | ||
end | ||
end | ||
|
||
# Represents an empty value | ||
class None < Maybe | ||
def get | ||
fail 'No such element' | ||
end | ||
# Represents an empty value | ||
class None < Maybe | ||
def get | ||
fail 'No such element' | ||
end | ||
|
||
def or_else(els = nil) | ||
block_given? ? yield : els | ||
end | ||
def or_else(els = nil) | ||
block_given? ? yield : els | ||
end | ||
|
||
# rubocop:disable PredicateName | ||
def is_some? | ||
false | ||
end | ||
# rubocop:disable PredicateName | ||
def is_some? | ||
false | ||
end | ||
|
||
def is_none? | ||
true | ||
end | ||
# rubocop:enable PredicateName | ||
def is_none? | ||
true | ||
end | ||
# rubocop:enable PredicateName | ||
|
||
def method_missing(*) | ||
None.new | ||
end | ||
def method_missing(*) | ||
self | ||
end | ||
|
||
private | ||
private | ||
|
||
def __enumerable_value | ||
[] | ||
end | ||
def __enumerable_value | ||
[] | ||
end | ||
end | ||
|
||
# rubocop:disable MethodName | ||
def Maybe(value) | ||
if value.nil? || (value.respond_to?(:length) && value.length == 0) | ||
None | ||
None() | ||
else | ||
Some(value) | ||
end | ||
end | ||
|
||
def Some(value) | ||
Maybe::Some.new(value) | ||
Some.new(value) | ||
end | ||
|
||
def None | ||
Maybe::None.new | ||
None.new | ||
end | ||
|
||
None = None() | ||
# rubocop:enable MethodName |
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