def decorate *decorators, target, default_type: nil
    
    if decorators.empty?
      raise NRSER::ArgumentError.new "Must provide at least one decorator"
    end
    
    method_ref = case target
    when ::String, ::Symbol
      resolve_method  name: target,
                      default_type: ( default_type || :instance )
    when ::UnboundMethod, ::Method
      target
    else
      raise NRSER::ArgumentError.new \
        "`target` (last arg) must be String, Symbol, Method or UnboundMethod",
        "found", target
    end
    
    if default_type.nil?
      default_type = if method_ref.is_a?( ::Method )
        :singleton
      else
        :instance
      end
    end
    
    decorated = \
      decorators.reverse_each.reduce method_ref do |decorated, decorator|
        
        # Resolve `decorator` to a `#call`-able if needed
        case decorator
        when ::Symbol, ::String
          decorator = resolve_method  name: decorator,
                                      default_type: default_type
                                      
        when ::Method, ::UnboundMethod
          # pass, it's already good to go
          
        when ::Class
          unless decorator.methods.include? :call
            decorator = decorator.new
          end
          
        else
          unless decorator.respond_to? :call
            raise TypeError.new \
              "Expected `decorator` to be one of",
              ::String,
              ::Symbol,
              ::Method,
              ::UnboundMethod,
              ::Class,
              "`#call`",
              "but found", decorator
          end
          
        end # case decorator
        
        Decoration.new decorator: decorator, decorated: decorated
        
      end # reduce
    
    definer = case method_ref
    when ::UnboundMethod
      :define_method
    when ::Method
      :define_singleton_method
    else
      raise NRSER::TypeError.new \
        "Expected {UnboundMethod} or {Method}, found", method_ref
    end
    
    send definer, method_ref.name do |*args, &block|
      decorated.call self, *args, &block
    end
    
  end
def decorate *decorators, target, default_type: nil
    
    if decorators.empty?
      raise NRSER::ArgumentError.new "Must provide at least one decorator"
    end
    
    method_ref = case target
    when ::String, ::Symbol
      resolve_method  name: target,
                      default_type: ( default_type || :instance )
    when ::UnboundMethod, ::Method
      target
    else
      raise NRSER::ArgumentError.new \
        "`target` (last arg) must be String, Symbol, Method or UnboundMethod",
        "found", target
    end
    
    if default_type.nil?
      default_type = if method_ref.is_a?( ::Method )
        :singleton
      else
        :instance
      end
    end
    
    decorated = \
      decorators.reverse_each.reduce method_ref do |decorated, decorator|
        
        # Resolve `decorator` to a `#call`-able if needed
        case decorator
        when ::Symbol, ::String
          decorator = resolve_method  name: decorator,
                                      default_type: default_type
                                      
        when ::Method, ::UnboundMethod
          # pass, it's already good to go
          
        when ::Class
          unless decorator.methods.include? :call
            decorator = decorator.new
          end
          
        else
          unless decorator.respond_to? :call
            raise TypeError.new \
              "Expected `decorator` to be one of",
              ::String,
              ::Symbol,
              ::Method,
              ::UnboundMethod,
              ::Class,
              "`#call`",
              "but found", decorator
          end
          
        end # case decorator
        
        Decoration.new decorator: decorator, decorated: decorated
        
      end # reduce
    
    definer = case method_ref
    when ::UnboundMethod
      :define_method
    when ::Method
      :define_singleton_method
    else
      raise NRSER::TypeError.new \
        "Expected {UnboundMethod} or {Method}, found", method_ref
    end
    
    send definer, method_ref.name do |*args, &block|
      decorated.call self, *args, &block
    end
    
  end
#resolve_method