class Steep::AST::Types::Intersection
def self.build(types:)
def self.build(types:) types.flat_map do |type| if type.is_a?(Intersection) type.types else [type] end end.map do |type| case type when AST::Types::Any return AST::Types::Any.instance() when AST::Types::Bot return AST::Types::Bot.instance when AST::Types::Top nil else type end end.compact.yield_self do |tys| dups = Set.new(tys) case dups.size when 0 AST::Types::Top.instance when 1 tys.first || raise else new(types: dups.to_a) end end end
def ==(other)
def ==(other) other.is_a?(Intersection) && other.types == types end
def each_child(&block)
def each_child(&block) if block types.each(&block) else types.each end end
def free_variables()
def free_variables() @fvs ||= begin set = Set.new types.each do |type| set.merge(type.free_variables) end set end end
def hash
def hash @hash ||= self.class.hash ^ types.hash end
def initialize(types:)
def initialize(types:) @types = types end
def level
def level [0] + level_of_children(types) end
def map_type(&block)
def map_type(&block) self.class.build( types: each_child.map(&block) ) end
def subst(s)
def subst(s) self.class.build(types: types.map {|ty| ty.subst(s) }) end
def to_s
def to_s "(#{types.map(&:to_s).join(" & ")})" end