<commit_before>module Dry
  module Monads
    module Do
      class Halt < StandardError
        attr_reader :result

        def initialize(result)
          super()

          @result = result
        end
      end

      def self.for(method)
        mod = Module.new do
          define_method(method) do |*args|
            begin
              super(*args) do |*ms|
                unwrapped = ms.map { |m| m.or { halt(m) }.value! }
                ms.size == 1 ? unwrapped[0] : unwrapped
              end
            rescue Halt => e
              e.result
            end
          end
        end

        Module.new do
          singleton_class.send(:define_method, :included) do |base|
            base.prepend(mod)
          end

          def halt(result)
            raise Halt.new(result)
          end
        end
      end
    end
  end
end<commit_msg>Add docs<commit_after>module Dry
  module Monads
    module Do
      class Halt < StandardError
        attr_reader :result

        def initialize(result)
          super()

          @result = result
        end
      end

      # Generates a module that passes a block to methods
      # that either unwraps a single-valued monadic value or halts
      # the execution.
      #
      # @example A complete example
      #
      #   class CreateUser
      #     include Dry::Monads::Result::Mixin
      #     include Dry::Monads::Try::Mixin
      #     include Dry::Monads::Do.for(:call)
      #
      #     attr_reader :user_repo
      #
      #     def initialize(:user_repo)
      #       @user_repo = user_repo
      #     end
      #
      #     def call(params)
      #       json = yield parse_json(params)
      #       hash = yield validate(json)
      #
      #       user_repo.transaction do
      #         user = yield create_user(hash[:user])
      #         yield create_profile(user, hash[:profile])
      #       end
      #
      #       Success(user)
      #     end
      #
      #     private
      #
      #     def parse_json(params)
      #       Try(JSON::ParserError) {
      #         JSON.parse(params)
      #       }.to_result
      #     end
      #
      #     def validate(json)
      #       UserSchema.(json).to_monad
      #     end
      #
      #     def create_user(user_data)
      #       Try(Sequel::Error) {
      #         user_repo.create(user_data)
      #       }.to_result
      #     end
      #
      #     def create_profile(user, profile_data)
      #       Try(Sequel::Error) {
      #         user_repo.create_profile(user, profile_data)
      #       }.to_result
      #     end
      #   end
      #
      # @param [Array<Symbol>] methods
      # @return [Module]
      def self.for(*methods)
        mod = Module.new do
          methods.each do |method|
            class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
              def #{ method }(*)
                super do |*ms|
                  unwrapped = ms.map { |m| m.or { halt(m) }.value! }
                  ms.size == 1 ? unwrapped[0] : unwrapped
                end
              rescue Halt => e
                e.result
              end
            RUBY
          end
        end

        Module.new do
          singleton_class.send(:define_method, :included) do |base|
            base.prepend(mod)
          end

          def halt(result)
            raise Halt.new(result)
          end
        end
      end
    end
  end
end
{'fraction_non_alphanumeric': 0.08896693005560433, 'fraction_numerical': 0.0014632718759145448, 'mean_word_length': 1.220922677063028, 'pattern_counts': {'":': 0, '<': 8, '<?xml version=': 0, '>': 6, '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': '1029787', 'n_tokens_mistral': 1014, 'n_tokens_neox': 979, 'n_words': 227}