如何编写动态类型检查器?

问题描述 投票:0回答:1

例如我有这样的签名

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
函数?

谢谢❤️

多里安

ruby types programming-languages
1个回答
0
投票

解决了,这就是要点:

      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
© www.soinside.com 2019 - 2024. All rights reserved.