Class: Literal::Types::UnionType

Inherits:
Object
  • Object
show all
Includes:
Enumerable, Literal::Type
Defined in:
lib/literal/types/union_type.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(queue) ⇒ UnionType

Returns a new instance of UnionType.



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/literal/types/union_type.rb', line 7

def initialize(queue)
	raise Literal::ArgumentError.new("_Union type must have at least one type.") if queue.size < 1
	types = []
	primitives = Set[]

	while queue.length > 0
		type = queue.shift
		case type
		when Literal::Types::UnionType
			queue.concat(type.types, type.primitives.to_a)
		when Array, Hash, String, Symbol, Integer, Float, Complex, Rational, true, false, nil
			primitives << type
		else
			types << type
		end
	end

	types.uniq!
	@types = types.freeze
	@primitives = primitives.freeze

	freeze
end

Instance Attribute Details

#primitivesObject (readonly)

Returns the value of attribute primitives.



31
32
33
# File 'lib/literal/types/union_type.rb', line 31

def primitives
  @primitives
end

#typesObject (readonly)

Returns the value of attribute types.



31
32
33
# File 'lib/literal/types/union_type.rb', line 31

def types
  @types
end

Instance Method Details

#===(value) ⇒ Object



37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/literal/types/union_type.rb', line 37

def ===(value)
	return true if @primitives.include?(value)

	types = @types

	i, len = 0, types.size
	while i < len
		return true if types[i] === value
		i += 1
	end

	false
end

#>=(other) ⇒ Object



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/literal/types/union_type.rb', line 70

def >=(other)
	types = @types
	primitives = @primitives

	case other
	when Literal::Types::UnionType
		types_have_at_least_one_subtype = other.types.all? do |other_type|
			primitives.any? { |p| Literal.subtype?(other_type, p) } || types.any? { |t| Literal.subtype?(other_type, t) }
		end

		primitives_have_at_least_one_subtype = other.primitives.all? do |other_primitive|
			primitives.any? { |p| Literal.subtype?(other_primitive, p) } || types.any? { |t| Literal.subtype?(other_primitive, t) }
		end

		types_have_at_least_one_subtype && primitives_have_at_least_one_subtype
	else
		types.any? { |t| Literal.subtype?(other, t) } || primitives.any? { |p| Literal.subtype?(other, p) }
	end
end

#[](key) ⇒ Object



60
61
62
63
64
# File 'lib/literal/types/union_type.rb', line 60

def [](key)
	if @primitives.include?(key) || @types.include?(key)
		key
	end
end

#deconstructObject



56
57
58
# File 'lib/literal/types/union_type.rb', line 56

def deconstruct
	to_a
end

#eachObject



51
52
53
54
# File 'lib/literal/types/union_type.rb', line 51

def each(&)
	@primitives.each(&)
	@types.each(&)
end

#fetch(key) ⇒ Object



66
67
68
# File 'lib/literal/types/union_type.rb', line 66

def fetch(key)
	self[key] or raise KeyError.new("Key not found: #{key.inspect}")
end

#inspectObject



33
34
35
# File 'lib/literal/types/union_type.rb', line 33

def inspect
	"_Union(#{to_a.map(&:inspect).join(', ')})"
end