例如我有这样的签名
sig(arguments) { Object.repeat }
sig(arguments) { Integer.maybe }
sig(arguments) { Object.repeat(1) }
sig(arguments) { Function | Class }
sig(arguments) { [Dictionary.repeat, Function.maybe] } # I have a hard time with this one
sig(arguments) { [Object, Function.maybe] }
sig(arguments) { [Object, Dictionary.maybe, Function.maybe] }
我有一个非常复杂且有缺陷的类型检查系统(对此感到非常羞愧)。
那么,你会如何编写这个
sig
函数?
谢谢❤️
多里安
解决了,这就是要点:
def check_types_of_arguments!
expected_index = 0
repeat_index = 0
actual_arguments.each do |actual|
expected = expected_arguments[expected_index]
if expected.is_a?(Repeat)
if valid_for?(expected:, actual:)
repeat_index += 1
elsif repeat_index >= expected.min_arguments
expected_index += 1
repeat_index = 0
else
raise(
Error::TypeError,
"#{function}: expected #{expected.name}, got #{actual.inspect}"
)
end
elsif valid_for?(expected:, actual:)
expected_index += 1
repeat_index = 0
else
raise(
Error::TypeError,
"#{function}: expected #{expected.name}, got #{actual.inspect}"
)
end
end
end
class Code
class Object
def self.maybe
Type::Maybe.new(self)
end
def self.name
"Object"
end
def self.repeat(minimum = 0, maximum = nil)
Type::Repeat.new(self, minimum:, maximum:)
end
def self.|(other)
Type::Or.new(self, other)
end
然后每种类型都有自己的有效?方法:
class Code
class Type
class Maybe < Type
attr_reader :clazz
def initialize(clazz)
@clazz = clazz
end
def valid?(argument)
!argument || valid_for?(expected: clazz, actual: argument)
end