# I have been play around the QuantumSuperpositions idea today and
# have come up with the following.
# 
# I have been play around the QuantumSuperpositions idea today and
# have come up with the following.
#
# All the classes that implement Enumerable should have 4
# more methods:
#
#    any?   all?   any   all
#
# the usage of any? and all? are just like what matz implemented in
# previous post.  For example:

  puts [1,2,3].any?{ |x| x > 2 }   # true
  puts [1,2,3].all?{ |x| x > 2 }   # false


# the two other methods can be used as following:

  puts [1,2,3].any > 2   # true
  puts [1,2,3].all > 2   # false

# the statements using "any" and "all" seems to be more intuitive and clean
# than the ones using "any?" and "all?".  However, "any?" and "all?" can take
# arbitrary expressions which "any" and "all" version can't.

a = [1,2,3].any  # or [1,2,3].all
puts a.type      # "Quantum", with a signature of "any?"
                 # notice that, it is no longer an array, because
                 # its comparison operator should have very different meaning
                 # than that of an array

b = a.dup * 2    # now a and b will be different "Quantum"

b.all            # now b has a signature of "all?"

p a > 2          # true
p b > 2          # false

p ( [1,2,3].any * 3 > 3 )    # true,  same as [3,6,9].any > 3
p ( [1,2,3].all * 3 > 3 )    # false, same as [3,6,9].all > 3
c = [1,2,3].all * 2          # same as c = [2,4,6].all

## another method is eigenstates

p c.eigenstates              # [2,4,6]

##  The usage can be nested:
a = [
   [1,1,3].any,
   [2,3,4].any,
   [3,6,7].all
   ].any


p a == 2              # true because ( [2,3,4].any == 2 )    => true
p a >  4              # false, can you see why?
p a.eigenstates       # [ [1,1,3], [2,3,4], [3,6,7] ]


## you can also compare two "Quantum"s

p [1,2,3].any < [2,5,6].all     # true
p [1,2,3].all < [2,5,6].all     # false


###  the following is still illegal :(

# a = 2 * [1,2,3]
# b = 2 > [1,2,3].any


##  This is not the same as the Perl QuantumSuperposition proposal, but I
##  believe it cover almost all the desired functionality of it.
##  Please comments!

## below is a reference implementation in plain ruby code:
##
## Ruby is PowerFul, you have to admit!


#  QuantumSuperposition.rb
class Quantum
   def initialize(o,t)
      @states = o
      @method = t
   end
   def any
      @method = "any?"
      self
   end
   def all
      @method = "all?"
      self
   end
   def eigenstates
      @states.collect { |x| x.type == self.type ? x.eigenstates : x }
   end
   def >(o)
      @states.method(@method).call { |x| o.type == self.type ? o < x : x > o }
   end
   def <(o)
      @states.method(@method).call { |x| o.type == self.type ? o > x : x < o }
   end
   def ==(o)
      @states.method(@method).call { |x| o.type == self.type ? o == x : x == o }
   end
   def method_missing(m, o)
      @states = @states.collect {|x| x.method(m).call(o) }
      self
   end
end

module Enumerable
   def any?
      self.each do |x|
         return true if yield(x)
      end
      return false
   end
   def all?
      self.each do |x|
         return false unless yield(x)
      end
      return true
   end

   def any
      return Quantum.new self, "any?"
   end
   def all
      return Quantum.new self, "all?"
   end
end