Проблема при определении переменных в racket

#recursion #scheme #racket

#рекурсия #схема #racket

Вопрос:

Я пытаюсь создать рекурсивную функцию, которая выбирает n элементов из списка, возвращая выбранные значения и список без значений, но когда я создаю свои переменные, я получаю эту ошибку:

 new-list: unbound identifier in: new-list
 

Вот мой код:

 (define(pick-randomr list n picked) ;;Picked always called as empty list
  (if(= n 0) (values list picked)
     ((let* ([aux list]
             [r (random (length aux))]              
             [value (list-ref aux r)]
             [new-picked (cons value picked)]
             [new-list (values (remove value aux))])
        (values aux r new-list))
      (pick-randomr new-list (- n 1) new-picked))))
 

Редактировать:
Строка, которая идет:

  (values aux r new-list)
 

просто не иметь пустого тела

Ответ №1:

Есть несколько проблем с вашим синтаксисом:

  • Вы не должны использовать list в качестве имени параметра, оно конфликтует со встроенной процедурой с тем же именем.
  • Не заключайте let* в две квадратные скобки, это распространенная ошибка, скобки не похожи на фигурные скобки в других языках, вы не должны использовать их для определения блока операторов, используйте begin для этого — но нам это не нужно в данном конкретном случае.
  • В первой полученной вами ошибке указано, что вы не должны определять a let* с пустым телом. Но выражение, которое вы добавили туда, неверно, вы должны написать выражения, которые используют переменные внутри let* , иначе new-list переменная не будет видна.

Это то, что вы хотели написать:

 (define (pick-randomr lst n picked)
  (if (= n 0)
      (values lst picked)
      (let* ([aux lst]
             [r (random (length aux))]              
             [value (list-ref aux r)]
             [new-picked (cons value picked)]
             [new-list (values (remove value aux))])
        (pick-randomr new-list (- n 1) new-picked))))
 

Давайте протестируем это:

 (pick-randomr '(1 2 3 4 5) 2 '())
=> '(1 2 5)
   '(3 4)