class Steep::AST::Types::Union
def self.build(types:, location: nil)
def self.build(types:, location: nil) return AST::Types::Bot.new if types.empty? return types.first if types.size == 1 types.flat_map do |type| if type.is_a?(Union) type.types else [type] end end.map do |type| case type when AST::Types::Any return AST::Types::Any.new(location: location) when AST::Types::Top return AST::Types::Top.new(location: location) when AST::Types::Bot nil else type end end.compact.uniq.yield_self do |tys| case tys.size when 0 AST::Types::Bot.new when 1 tys.first else new(types: tys, location: location) end end end
def ==(other)
def ==(other) other.is_a?(Union) && Set.new(other.types) == Set.new(types) end
def free_variables
def free_variables @fvs ||= Set.new.tap do |set| types.each do |type| set.merge(type.free_variables) end end end
def hash
def hash @hash ||= self.class.hash ^ types.sort_by(&:to_s).hash end
def initialize(types:, location: nil)
def initialize(types:, location: nil) @types = types @location = location end
def level
def level [0] + level_of_children(types) end
def subst(s)
def subst(s) self.class.build(location: location, types: types.map {|ty| ty.subst(s) }) end
def to_s
def to_s "(#{types.map(&:to_s).join(" | ")})" end
def with_location(new_location)
def with_location(new_location) self.class.new(types: types, location: new_location) end