Class: Typical::Type::Union

Inherits:
Typical::Type show all
Defined in:
lib/typical/type/union.rb

Instance Attribute Summary collapse

Attributes inherited from Typical::Type

#type

Instance Method Summary collapse

Methods inherited from Typical::Type

#eql?, #nullable?, of

Constructor Details

#initialize(types = []) ⇒ Union

Returns a new instance of Union.

Raises:

  • (TypeError)


6
7
8
9
# File 'lib/typical/type/union.rb', line 6

def initialize(types = [])
  raise TypeError, "Requires an array of types" unless types.is_a?(::Array)
  @types = ::Set.new(types.map { |type| Type.of(type) })
end

Instance Attribute Details

#typesObject (readonly)

Returns the value of attribute types.



4
5
6
# File 'lib/typical/type/union.rb', line 4

def types
  @types
end

Instance Method Details

#==(other) ⇒ Object



21
22
23
# File 'lib/typical/type/union.rb', line 21

def ==(other)
  other.is_a?(Union) && @types == other.types
end

#empty?Boolean

Returns:

  • (Boolean)


17
18
19
# File 'lib/typical/type/union.rb', line 17

def empty?
  @types.empty?
end

#hashObject



25
26
27
# File 'lib/typical/type/union.rb', line 25

def hash
  @types.hash
end

#inspectObject



67
68
69
# File 'lib/typical/type/union.rb', line 67

def inspect
  "#<Type:Union [#{@types.map(&:inspect).join(", ")}]>"
end

#normalize(unwrap_single_type = true) ⇒ Object



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/typical/type/union.rb', line 34

def normalize(unwrap_single_type = true)
  normalized = Union.new
  types = self.types.dup

  arrays = types.select { |type| type.type == ::Array }
  unless arrays.empty?
    types -= arrays
    normalized |= Array.new(arrays.map(&:values).reduce(:|).types.to_a).normalize
  end

  sets = types.select { |type| type.type == ::Set }
  unless sets.empty?
    types -= sets
    normalized |= Set.new(::Set.new(sets.map(&:values).reduce(:|).types.to_a)).normalize
  end

  hashes = types.select { |type| type.type == ::Hash }
  unless hashes.empty?
    types -= hashes
    hash = Hash.new
    hash.keys |= hashes.map(&:keys).reduce(:|)
    hash.values |= hashes.map(&:values).reduce(:|)
    normalized |= hash.normalize
  end

  # Add remainder
  types.each { |type| normalized |= type.normalize }
  # If there’s only 1 type, unwrap it from the union type.
  normalized = normalized.types.first if unwrap_single_type && normalized.types.size == 1

  normalized
end

#prominent_typeObject



11
12
13
14
15
# File 'lib/typical/type/union.rb', line 11

def prominent_type
  copy = types.dup
  copy.delete_if { |type| type.type == NilClass }
  copy.first if copy.size == 1
end

#|(other) ⇒ Object

Raises:

  • (TypeError)


29
30
31
32
# File 'lib/typical/type/union.rb', line 29

def |(other)
  raise TypeError, "Can only make a union of Type and subclasses of Type" unless other.is_a?(Type)
  Union.new((types + other.types).to_a)
end