<commit_before>module Results
  def Why(arg)
    case arg
    when Because then Why::One.new(arg)
    when Array   then Why::Many.new(arg)
    when Hash    then Why::Named.new(arg)
    else raise TypeError, "can't convert #{arg.class} into Why"
    end
  end

  module Why

    class Base
      def +(that)
        raise(ArgumentError, 'not a valid Why') unless that.is_a? Why::Base
        self.promote(that) + that.promote(self)
      end

      private

      def initialize
        raise(TypeError, 'cannot instantiate abstract class') if self.class == Results::Why::Base
      end

      def promote(that)
        case that
        when One   then self.to_many
        when Many  then self.to_many
        when Named then self.to_named
        end
      end
    end

    # Explains a Bad caused by exactly one Because
    class One < Base
      def initialize(because)
        raise ArgumentError, 'not a Because' unless because.is_a? Because
        @because = because
      end

      attr_reader :because

      def ==(that)
        that.is_a?(One) && that.because == self.because
      end

      def to_many
        Many.new([self.because])
      end

      def to_named
        to_many.to_named
      end
    end

    # Explains a Bad caused by at least one Because
    class Many < Base
      def initialize(becauses)
        raise ArgumentError, 'not an Array of at least one Because' unless
          becauses.is_a?(Array) && !becauses.empty? && becauses.all? { |b| b.is_a? Because }
        @becauses = becauses
      end

      attr_reader :becauses

      def ==(that)
        that.is_a?(Many) && that.becauses == self.becauses
      end

      def to_many
        self
      end

      def to_named(name = :base)
        Named.new({ name => self.becauses })
      end

      def +(that)
        case that
        when Many then Many.new(self.becauses + that.becauses)
        else super
        end
      end
    end

    # Explains a Bad caused by at least one Because, each attributed to a named field
    class Named < Base
      def initialize(becauses_by_name)
        raise ArgumentError, 'not a Hash whose values are Arrays of at least one Because' unless
          becauses_by_name.is_a?(Hash) && !becauses_by_name.empty? &&
            becauses_by_name.values.all? { |v| v.is_a?(Array) && !v.empty? &&
              v.all? { |b| b.is_a? Because } }
        @becauses_by_name = becauses_by_name
      end

      attr_reader :becauses_by_name

      def ==(that)
        that.is_a?(Named) && that.becauses_by_name == self.becauses_by_name
      end

      def to_named
        self
      end

      def +(that)
        case that
        when Named
          Named.new(self.becauses_by_name.merge(that.becauses_by_name) { |_, self_val, that_val| self_val + that_val })
        else super
        end
      end

      def promote(that)
        self
      end
    end
  end

end<commit_msg>Rename parameter to binary operations as 'other'<commit_after>module Results
  def Why(arg)
    case arg
    when Because then Why::One.new(arg)
    when Array   then Why::Many.new(arg)
    when Hash    then Why::Named.new(arg)
    else raise TypeError, "can't convert #{arg.class} into Why"
    end
  end

  module Why

    class Base
      def +(other)
        raise(ArgumentError, 'not a valid Why') unless other.is_a? Why::Base
        self.promote(other) + other.promote(self)
      end

      private

      def initialize
        raise(TypeError, 'cannot instantiate abstract class') if self.class == Results::Why::Base
      end

      def promote(other)
        case other
        when One   then self.to_many
        when Many  then self.to_many
        when Named then self.to_named
        end
      end
    end

    # Explains a Bad caused by exactly one Because
    class One < Base
      def initialize(because)
        raise ArgumentError, 'not a Because' unless because.is_a? Because
        @because = because
      end

      attr_reader :because

      def ==(other)
        other.is_a?(One) && other.because == self.because
      end

      def to_many
        Many.new([self.because])
      end

      def to_named
        to_many.to_named
      end
    end

    # Explains a Bad caused by at least one Because
    class Many < Base
      def initialize(becauses)
        raise ArgumentError, 'not an Array of at least one Because' unless
          becauses.is_a?(Array) && !becauses.empty? && becauses.all? { |b| b.is_a? Because }
        @becauses = becauses
      end

      attr_reader :becauses

      def ==(other)
        other.is_a?(Many) && other.becauses == self.becauses
      end

      def to_many
        self
      end

      def to_named(name = :base)
        Named.new({ name => self.becauses })
      end

      def +(other)
        case other
        when Many then Many.new(self.becauses + other.becauses)
        else super
        end
      end
    end

    # Explains a Bad caused by at least one Because, each attributed to a named field
    class Named < Base
      def initialize(becauses_by_name)
        raise ArgumentError, 'not a Hash whose values are Arrays of at least one Because' unless
          becauses_by_name.is_a?(Hash) && !becauses_by_name.empty? &&
            becauses_by_name.values.all? { |v| v.is_a?(Array) && !v.empty? &&
              v.all? { |b| b.is_a? Because } }
        @becauses_by_name = becauses_by_name
      end

      attr_reader :becauses_by_name

      def ==(other)
        other.is_a?(Named) && other.becauses_by_name == self.becauses_by_name
      end

      def to_named
        self
      end

      def +(other)
        case other
        when Named
          Named.new(self.becauses_by_name.merge(other.becauses_by_name) { |_, self_val, other_val| self_val + other_val })
        else super
        end
      end

      def promote(other)
        self
      end
    end
  end

end
{'fraction_non_alphanumeric': 0.08295087540370559, 'fraction_numerical': 0.0, 'mean_word_length': 1.9732187973724102, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 5, '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': '2532215', 'n_tokens_mistral': 1834, 'n_tokens_neox': 1791, 'n_words': 539}