2010-10-27 67 views
0

正如标题所述,Ruby是否允许Cartesian产品类型?我在任何地方都找不到任何东西。红宝石,它是否允许笛卡尔产品构造函数?

感谢

+0

它允许吗?是。它是否在标准库中实现?可能不会,但执行起来并不困难 – Chubas 2010-10-27 17:13:21

+0

@Chubas:我认为“执行起来并不困难”是一种“粗暴”的轻描淡写。在实现产品类型之前,首先必须实现一个类型系统,尽管[Diamondback Ruby](http://WWW.CS.UMD.Edu/projects/PL/druby/)项目的工作非常出色,那可能仍然是一个博士级多年研究项目。 – 2010-10-28 09:53:34

+0

那么,Trevor真的想要什么? (除此之外,当然,从一个正确的教训,事实上类型真的不是他认为他们是......) – 2010-10-28 21:59:16

回答

3

红宝石不允许类型所有,至少不是在你似乎可以用单词“类型”的意义。因此,它显然不支持产品类型。 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项目是一个很好的起点。它包括元组类型,例如,这是产品类型的一个实例。