Class: TypedRb::Types::TyFunction
Instance Attribute Summary collapse
Attributes inherited from Type
#node
Instance Method Summary
collapse
Methods inherited from Type
#either?, #stack_jump?
Constructor Details
#initialize(from, to, parameters_info = nil, node = nil) ⇒ TyFunction
Returns a new instance of TyFunction.
9
10
11
12
13
14
15
16
17
18
19
20
|
# File 'lib/typed/types/ty_function.rb', line 9
def initialize(from, to, parameters_info = nil, node = nil)
super(node)
@from = from.is_a?(Array) ? from : [from]
@to = to
@parameters_info = parameters_info
if @parameters_info.nil?
@parameters_info = @from.map { |type| [:req, type] }
end
@arity = parse_function_arity
@min_arity = parse_min_function_arity
@block_type = nil
end
|
Instance Attribute Details
Returns the value of attribute arity.
6
7
8
|
# File 'lib/typed/types/ty_function.rb', line 6
def arity
@arity
end
|
#block_type ⇒ Object
Returns the value of attribute block_type.
6
7
8
|
# File 'lib/typed/types/ty_function.rb', line 6
def block_type
@block_type
end
|
Returns the value of attribute from.
6
7
8
|
# File 'lib/typed/types/ty_function.rb', line 6
def from
@from
end
|
#min_arity ⇒ Object
Returns the value of attribute min_arity.
6
7
8
|
# File 'lib/typed/types/ty_function.rb', line 6
def min_arity
@min_arity
end
|
45
46
47
|
# File 'lib/typed/types/ty_function.rb', line 45
def name
@name || 'lambda'
end
|
#parameters_info ⇒ Object
Returns the value of attribute parameters_info.
6
7
8
|
# File 'lib/typed/types/ty_function.rb', line 6
def parameters_info
@parameters_info
end
|
Returns the value of attribute to.
6
7
8
|
# File 'lib/typed/types/ty_function.rb', line 6
def to
@to
end
|
Instance Method Details
#<=>(other) ⇒ Object
120
121
122
123
124
125
126
127
|
# File 'lib/typed/types/ty_function.rb', line 120
def <=>(other)
if other.is_a?(TyFunction)
raise 'Non implemented yet'
else
TyObject.new(Method, node) <=> other
end
end
|
#apply_bindings(bindings_map) ⇒ Object
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
# File 'lib/typed/types/ty_function.rb', line 99
def apply_bindings(bindings_map)
from.each_with_index do |from_type, i|
if from_type.is_a?(Polymorphism::TypeVariable)
from_type.apply_bindings(bindings_map)
from[i] = from_type.bound if from_type.bound
elsif from_type.is_a?(TyGenericSingletonObject) || from_type.is_a?(TyGenericObject)
from_type.apply_bindings(bindings_map)
end
end
if to.is_a?(Polymorphism::TypeVariable)
@to = to.apply_bindings(bindings_map)
@to = to.bound if to.bound
elsif to.respond_to?(:apply_bindings)
@to = to.apply_bindings(bindings_map)
end
block_type.apply_bindings(bindings_map) if block_type && block_type.generic?
self
end
|
#arg_compatible?(num_args) ⇒ Boolean
27
28
29
|
# File 'lib/typed/types/ty_function.rb', line 27
def arg_compatible?(num_args)
num_args >= min_arity && (arity == Float::INFINITY || arity == num_args)
end
|
#check_args_application(actual_arguments, context) ⇒ Object
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
# File 'lib/typed/types/ty_function.rb', line 49
def check_args_application(actual_arguments, context)
parameters_info.each_with_index do |(require_info, arg_name), index|
actual_argument = actual_arguments[index]
from_type = from[index]
if actual_argument.nil? && require_info != :opt
error_msg = "Type error checking function '#{name}': Missing mandatory argument #{arg_name} in #{receiver_type}##{message}"
fail TypeCheckError.new(error_msg, node)
else
unless actual_argument.nil? actual_argument_type = actual_argument.check_type(context)
unless actual_argument_type.compatible?(from_type, :lt)
error_message = "Type error checking function '#{name}': #{error_message} #{from_type} expected, #{argument_type} found"
fail TypeCheckError.new(error_message, node)
end
end
end
end
self
end
|
#compatible?(other_type, relation = :lt) ⇒ Boolean
(S1 -> S2) < (T1 -> T2) => T1 < S1 && S2 < T2 Contravariant in the input, covariant in the output
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
|
# File 'lib/typed/types/ty_function.rb', line 71
def compatible?(other_type, relation = :lt)
if other_type.is_a?(TyGenericFunction)
other_type.compatible?(self, relation == :lt ? :gt : :lt)
elsif other_type.is_a?(TyFunction)
other_from = deconstruct_from_arguments(other_type)
from.each_with_index do |arg, i|
other_arg = other_from[i]
return false unless arg.compatible?(other_arg, :gt)
end
return false unless to.compatible?(other_type.to, :lt)
else
fail TypeCheckError.new("Type error checking function '#{name}': Comparing function type with no function type")
end
true
end
|
#deconstruct_from_arguments(other_type) ⇒ Object
87
88
89
90
91
92
93
94
95
96
97
|
# File 'lib/typed/types/ty_function.rb', line 87
def deconstruct_from_arguments(other_type)
if from.size == other_type.from.size
other_type.from
elsif from.size > 1 && other_type.from.size == 1 && other_type.from.first.ruby_type.ancestors.include?(Pair)
other_type.from.first.type_vars(recursive: false)
elsif from.size > 1 && other_type.from.size == 1 && other_type.from.first.ruby_type.ancestors.include?(Array)
other_type.from.first.type_vars(recursive: false) * from.size
else
other_type.from
end
end
|
#dynamic? ⇒ Boolean
35
36
37
|
# File 'lib/typed/types/ty_function.rb', line 35
def dynamic?
false
end
|
#generic? ⇒ Boolean
31
32
33
|
# File 'lib/typed/types/ty_function.rb', line 31
def generic?
false
end
|
39
40
41
42
43
|
# File 'lib/typed/types/ty_function.rb', line 39
def to_s
args = @from.map(&:to_s).join(', ')
args = "#{args}, &#{block_type}" if block_type
"(#{args} -> #{@to})"
end
|
#with_block_type(type) ⇒ Object
22
23
24
25
|
# File 'lib/typed/types/ty_function.rb', line 22
def with_block_type(type)
@block_type = type
self
end
|