Class: Rigor::Type::Intersection

Inherits:
Object
  • Object
show all
Includes:
AcceptanceRouter, PlainLattice, ValueSemantics
Defined in:
lib/rigor/type/intersection.rb,
sig/rigor/type.rbs

Overview

Intersection[M1, M2, …] — value set is the meet of every member's value set. The carrier composes refinements that share a base, in particular the catalogued non-empty-lowercase-string (= Difference[String, ""] & Refined[String, :lowercase]) and non-empty-uppercase-string shapes from imported-built-in-types.md. See ADR-3 for the OQ3 working decision and the rationale for keeping Intersection a thin wrapper rather than per-shape carriers.

Construction MUST go through Type::Combinator.intersection (or the per-name factories Combinator.non_empty_lowercase_string / Combinator.non_empty_uppercase_string). The factory:

  • flattens nested intersections,
  • drops Top members (Top is the identity of intersection),
  • collapses to Bot if any member is Bot (Bot is absorbing),
  • deduplicates structurally-equal members,
  • sorts the surviving members by describe(:short) so two structurally-equal intersections built in different orders compare equal,
  • returns Top for the empty intersection,
  • returns the lone member for a 1-element intersection (so the carrier is never inhabited by a degenerate single-member shape).

Direct .new callers MUST pass an already-normalised member list and are expected to be tests or the combinator itself.

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from ValueSemantics

included

Constructor Details

#initialize(members) ⇒ Intersection

Returns a new instance of Intersection.

Parameters:

  • members (Array[Type::t])


35
36
37
38
# File 'lib/rigor/type/intersection.rb', line 35

def initialize(members)
  @members = members.dup.freeze
  freeze
end

Instance Attribute Details

#membersArray[Type::t] (readonly)

Returns the value of attribute members.

Returns:

  • (Array[Type::t])


33
34
35
# File 'lib/rigor/type/intersection.rb', line 33

def members
  @members
end

Instance Method Details

#==Boolean

Parameters:

  • other (Object)

Returns:

  • (Boolean)


206
# File 'sig/rigor/type.rbs', line 206

def ==: (untyped other) -> bool

#acceptsAcceptsResult

Parameters:

  • other (Type::t)
  • mode: (accepts_mode)

Returns:



205
# File 'sig/rigor/type.rbs', line 205

def accepts: (Type::t other, ?mode: accepts_mode) -> AcceptsResult

#botTrinary

Returns:



203
# File 'sig/rigor/type.rbs', line 203

def bot: () -> Trinary

#describe(verbosity = :short) ⇒ String

Parameters:

  • verbosity (Symbol) (defaults to: :short)

Returns:

  • (String)


40
41
42
43
44
45
# File 'lib/rigor/type/intersection.rb', line 40

def describe(verbosity = :short)
  named = canonical_name
  return named if named

  members.map { |m| m.describe(verbosity) }.join(" & ")
end

#dynamicTrinary

Returns:



204
# File 'sig/rigor/type.rbs', line 204

def dynamic: () -> Trinary

#erase_to_rbsString

An intersection of refinements over the same base type erases to that base. We use the first member's erasure because the v0.0.4 catalogue (non-empty-lowercase-string etc.) is restricted to same-base composition; richer cross-base intersections will need a stricter erasure rule (likely "lowest common ancestor" via the inference engine's class hierarchy).

Returns:

  • (String)


51
52
53
# File 'lib/rigor/type/intersection.rb', line 51

def erase_to_rbs
  members.first.erase_to_rbs
end

#hashInteger

Returns:

  • (Integer)


207
# File 'sig/rigor/type.rbs', line 207

def hash: () -> Integer

#inspectString

Returns:

  • (String)


63
64
65
# File 'lib/rigor/type/intersection.rb', line 63

def inspect
  "#<Rigor::Type::Intersection #{describe(:short)}>"
end

#topTrinary

Returns:



202
# File 'sig/rigor/type.rbs', line 202

def top: () -> Trinary