Ruby,它是否允许Cartesian产品构造函数?

时间:2010-10-27 16:52:41

标签: ruby constructor cartesian-product

正如标题所述,Ruby是否允许Cartesian产品类型?我在任何地方都找不到任何东西。

由于

1 个答案:

答案 0 :(得分:3)

Ruby根本不允许类型 ,至少在你似乎使用“type”这个词的意义上。因此,它显然也不支持产品类型。

Ruby是一种所谓的“动态类型”语言(使用单词“type”的实用,程序员 - 行话定义)或无类型语言(使用数学,类型理论定义),所以谈论“产品”类型“根本没有意义。

或者,如果您愿意,您可以将动态类型语言看作静态类型语言,只有一种类型,它是所有动态类型的总和类型。

但是,

class Tuple
  include Enumerable; include Comparable

  class << self
    alias_method :[], :new

    def call(length)
      class_name = :"Tuple#{length}"
      return const_get class_name if const_defined? class_name
      const_set class_name, Class.new(self) {
        (@length = length).times do |i| define_method :"_#{i+1}" do @ary[i] end end
      }
    end
  end

  def to_s; "(#{@ary.join(', ')})" end
  def inspect; "#<#{self.class} (#{@ary.map(&:inspect).join(', ')})>" end
  def to_a; @ary.dup end
  def [](*args) @ary[*args] end
  def each(*args, &block) @ary.each(*args, &block) end

  def <=>(other)
    raise TypeError unless other.is_a? self.class
    raise TypeError unless each_with_index.all? {|el, i| other.instance_variable_get(:@ary)[i].instance_of?(el.class) }
    map.with_index {|el, i| el <=> other.instance_variable_get(:@ary)[i] }.find(0) {|cmp| !cmp.zero? }
  end

  def initialize(*args)
    raise ArgumentError unless args.length == self.class.instance_variable_get(:@length)
    (@ary = args).freeze
  end
end

这将为您提供构建n元组的方法,当然这是产品类型的特例。例如,这个:

t3 = Tuple.(3)[1, :two, 'three']

将使用元组类型(Fixnum, Symbol, String)构造一个三元组,这是产品类型Fixnum × Symbol × String的特例。但是没有办法在Ruby中表示和/或强制执行这些类型。

如果您想深入了解Ruby的类型系统,Diamondback Ruby项目是一个很好的起点。它包括元组类型,例如,它们是产品类型的实例。