lib/rumonade/monad.rb in rumonade-0.4.2 vs lib/rumonade/monad.rb in rumonade-0.4.3
- old
+ new
@@ -55,13 +55,19 @@
# [Some(Some(1)), Some(Some(None))], [None]].flatten
# #=> [1]
#
def flatten_with_monad(depth=nil)
if depth.is_a? Integer
- depth.times.inject(self) {|e, _| e.shallow_flatten }
+ depth.times.inject(self) { |e, _| e.shallow_flatten }
else
- bind { |x| x.is_a?(Monad) ? x.flatten_with_monad : self.class.unit(x) }
+ bind do |x|
+ if x.is_a?(Monad) && x.can_flatten_in_monad?
+ x.flatten_with_monad
+ else
+ self.class.unit(x)
+ end
+ end
end
end
# Returns a monad whose elements are all those elements of this monad for which the given predicate returned true
def select(lam = nil, &blk)
@@ -82,8 +88,16 @@
# [1, None].shallow_flatten
# #=> [1]
#
def shallow_flatten
bind { |x| x.is_a?(Monad) ? x : self.class.unit(x) }
+ end
+
+ # Returns +true+ if #flatten_with_monad can call recursively on contained
+ # values members (eg. elements of an array).
+ #
+ # NOTE: Is overridden in Hash.
+ def can_flatten_in_monad?
+ true
end
end
end