As the title states, does Ruby allow Cartesian product types? I can't find anything on it anywhere.
Thanks
As the title states, does Ruby allow Cartesian product types? I can't find anything on it anywhere.
Thanks
Ruby doesn't allow types at all, at least not in the sense that you seem to be using the word "type". Therefore, it obviously doesn't support product types, either.
Ruby is a so-called "dynamically typed" language (using the pragmatic, programmer-jargon definition of the word "type") or an untyped language (using the mathematical, type-theoretic definition), so talking about "product types" simply doesn't make sense at all.
Or, if you want to, you can see a dynamically typed language as a statically typed language with only a single type which is the sum type of all dynamic types.
However, you can obviously construct values that would have a product type if Ruby had types at all:
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_ary; @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
This will give you a way to construct n-Tuples, which of course are special cases of product types. For example, this:
t3 = Tuple.(3)[1, :two, 'three']
will construct a triple with the tuple type (Fixnum, Symbol, String)
, which is a special case of the product type Fixnum × Symbol × String
. But there is no way to represent and/or enforce those types in Ruby.
If you want to look deeper into type systems for Ruby, the Diamondback Ruby project is a good starting point. It includes tuple types, for example, which are an instance of product types.