Class: Qrb::UnionType
Overview
A union type (aka algebraic type) allows capturing information types through generalization/disjunction. For instance,
Numeric = Int|Real
This class allows capturing such union types, as follows:
Int = BuiltinType.new(Fixnum)
Real = BuiltinType.new(Float)
Numeric = UnionType.new([ Int, Real ])
When transforming a value through ‘dress`, the different candidate types are tried in specified order. The first one that succeeds at building the value ends the process and the value is simply returned. Accordingly, the concrete representation will be
R(Numeric) = R(Int) ^ R(Real) = Fixnum ^ Float = Numeric
where ‘^` denotes the `least common super type` operator on ruby classes.
Accordingly, the ‘dress` transformation function has the following signature:
dress :: Alpha -> Numeric throws TypeError
dress :: Object -> Numeric throws TypeError
Instance Attribute Summary collapse
-
#candidates ⇒ Object
readonly
Returns the value of attribute candidates.
Instance Method Summary collapse
- #==(other) ⇒ Object (also: #eql?)
- #default_name ⇒ Object
-
#dress(value, handler = DressHelper.new) ⇒ Object
Invoke ‘dress` on each candidate type in turn.
- #hash ⇒ Object
- #include?(value) ⇒ Boolean
-
#initialize(candidates, name = nil) ⇒ UnionType
constructor
A new instance of UnionType.
Methods inherited from Type
Constructor Details
#initialize(candidates, name = nil) ⇒ UnionType
Returns a new instance of UnionType.
32 33 34 35 36 37 38 39 |
# File 'lib/qrb/type/union_type.rb', line 32 def initialize(candidates, name = nil) unless candidates.all?{|c| c.is_a?(Type) } raise ArgumentError, "[Qrb::Type] expected, got #{candidates}" end super(name) @candidates = candidates.freeze end |
Instance Attribute Details
#candidates ⇒ Object (readonly)
Returns the value of attribute candidates.
40 41 42 |
# File 'lib/qrb/type/union_type.rb', line 40 def candidates @candidates end |
Instance Method Details
#==(other) ⇒ Object Also known as: eql?
67 68 69 70 |
# File 'lib/qrb/type/union_type.rb', line 67 def ==(other) return false unless other.is_a?(UnionType) set_equal?(candidates, other.candidates) end |
#default_name ⇒ Object
63 64 65 |
# File 'lib/qrb/type/union_type.rb', line 63 def default_name candidates.map(&:name).join('|') end |
#dress(value, handler = DressHelper.new) ⇒ Object
Invoke ‘dress` on each candidate type in turn. Return the value returned by the first one that does not fail. Fail with an TypeError if no candidate succeeds at tranforming `value`.
49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/qrb/type/union_type.rb', line 49 def dress(value, handler = DressHelper.new) # Do nothing on TypeError as the next candidate could be the good one! candidates.each do |c| success, uped = handler.just_try do c.dress(value, handler) end return uped if success end # No one succeed, just fail handler.failed!(self, value) end |
#hash ⇒ Object
73 74 75 |
# File 'lib/qrb/type/union_type.rb', line 73 def hash self.class.hash ^ set_hash(self.candidates) end |
#include?(value) ⇒ Boolean
42 43 44 |
# File 'lib/qrb/type/union_type.rb', line 42 def include?(value) candidates.any?{|c| c.include?(value) } end |