docs: def evaluator(evaluate):
      """Return an inspyred evaluator function based on the given function.
      
      This function generator takes a function that evaluates only one
      candidate. The generator handles the iteration over each candidate 
      to be evaluated.
  
      The given function ``evaluate`` must have the following signature::
      
          fitness = evaluate(candidate, args)
          
      This function is most commonly used as a function decorator with
      the following usage::
      
          @evaluator
          def evaluate(candidate, args):
              # Implementation of evaluation
              pass
              
      The generated function also contains an attribute named
      ``single_evaluation`` which holds the original evaluation function.
      In this way, the original single-candidate function can be
      retrieved if necessary.
      
      """
      @functools.wraps(evaluate)
      def inspyred_evaluator(candidates, args):
          fitness = []
          for candidate in candidates:
              fitness.append(evaluate(candidate, args))
          return fitness
      inspyred_evaluator.single_evaluation = evaluate
      return inspyred_evaluator