<commit_before>require 'composite_type'

module CompositeType
  # A declarative matching schema.
  class Schema
    attr_accessor :proto, :match
    class << self
      alias :[] :new
    end

    def initialize proto
      @proto = proto
      @match = build proto
    end

    def === instance
      @match === instance
    end

    def build proto
      case proto
      when Schema, Base, Module
        proto
      when HashLike
        h = { }
        proto.each do | k, v |
          h[build(k)] = build(v)
        end
        HashType[h]
      when Enumerable
        EnumerableType[proto.map{|x| build x}]
      else
        Literal[proto]
      end
    end

    def inspect verbose = false
      return super() if verbose
      "#{self.class}[#{@proto.inspect}]"
    end

    module Ellipsis
      def self.=== instance
        true
      end
    end

    class Base
      attr_reader :matcher

      class << self
        alias :[] :new
      end

      def initialize proto
        @matcher = proto
      end

      def inspect verbose = false
        return super() if verbose
        "#{self.class}[#{@matcher.inspect}]"
      end
    end

    class Optional < Base
      def === instance
        @matcher === instance
      end
    end

    class Literal < Base
      def === instance
        @matcher == instance
      end
    end

    class EnumerableType < Base
      def initialize proto
        @matcher = proto
        compile!
      end

      def compile!
        matchers = [ ]
        last = lambda do | instance, i |
          i == instance.size
        end
        i = 0
        @matcher.each do | et |
          case
          when Ellipsis == et
            last = lambda do | instance, i |
              true
            end
          when Optional === et
            matchers << lambda do | instance, i |
              if et === instance[i]
                i += 1
              end
              i
            end
          else
            matchers << lambda do | instance, i |
              i < instance.size && et === instance[i] && i + 1
            end
          end
        end
        matchers.push last
        @proc = lambda do | instance |
          i = 0
          matchers.each do | f |
            unless i = f.call(instance, i)
              return false
            end
          end
          true
        end
        ap(matchers: matchers)
        self
      end

      def === instance
        return false unless Enumerable === instance
        return @proc.call(instance) if @proc
        i = 0
        matches = 0
        @matcher.each do | et |
          case
          when Ellipsis == et
            return true
          when Optional === et
            if et === instance[i]
              i += 1
              matches += 1
            end
          else
            return false unless i < instance.size && et === instance[i]
            matches += 1
            i += 1
          end
        end
        matches == instance.size
      end
    end<commit_msg>Remove redundant matches var.<commit_after>require 'composite_type'

module CompositeType
  # A declarative matching schema.
  class Schema
    attr_accessor :proto, :match
    class << self
      alias :[] :new
    end

    def initialize proto
      @proto = proto
      @match = build proto
    end

    def === instance
      @match === instance
    end

    def build proto
      case proto
      when Schema, Base, Module
        proto
      when HashLike
        h = { }
        proto.each do | k, v |
          h[build(k)] = build(v)
        end
        HashType[h]
      when Enumerable
        EnumerableType[proto.map{|x| build x}]
      else
        Literal[proto]
      end
    end

    def inspect verbose = false
      return super() if verbose
      "#{self.class}[#{@proto.inspect}]"
    end

    module Ellipsis
      def self.=== instance
        true
      end
    end

    class Base
      attr_reader :matcher

      class << self
        alias :[] :new
      end

      def initialize proto
        @matcher = proto
      end

      def inspect verbose = false
        return super() if verbose
        "#{self.class}[#{@matcher.inspect}]"
      end
    end

    class Optional < Base
      def === instance
        @matcher === instance
      end
    end

    class Literal < Base
      def === instance
        @matcher == instance
      end
    end

    class EnumerableType < Base
      def initialize proto
        @matcher = proto
        compile!
      end

      def compile!
        matchers = [ ]
        last = lambda do | instance, i |
          i == instance.size
        end
        i = 0
        @matcher.each do | et |
          case
          when Ellipsis == et
            last = lambda do | instance, i |
              true
            end
          when Optional === et
            matchers << lambda do | instance, i |
              if et === instance[i]
                i += 1
              end
              i
            end
          else
            matchers << lambda do | instance, i |
              i < instance.size && et === instance[i] && i + 1
            end
          end
        end
        matchers.push last
        @proc = lambda do | instance |
          i = 0
          matchers.each do | f |
            unless i = f.call(instance, i)
              return false
            end
          end
          true
        end
        ap(matchers: matchers)
        self
      end

      def === instance
        return false unless Enumerable === instance
        return @proc.call(instance) if @proc

        i = 0
        @matcher.each do | et |
          case
          when Ellipsis == et
            return true
          when Optional === et
            if et === instance[i]
              i += 1
            end
          else
            return false unless i < instance.size && et === instance[i]
            i += 1
          end
        end
        i == instance.size
      end
    end
{'fraction_non_alphanumeric': 0.07840509298039873, 'fraction_numerical': 0.002848048249287988, 'mean_word_length': 1.1892189218921891, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2106750', 'n_tokens_mistral': 1623, 'n_tokens_neox': 1558, 'n_words': 536}