Создайте список с одинаковыми n элементами - PullRequest
0 голосов
/ 17 января 2019

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

Я пробовал это:

#lang racket

(build-list 5 (lambda () '*))

Но я получаю ошибку:

build-list: contract violation
  expected: (exact-nonnegative-integer? . -> . any/c)
  given: #<procedure>

Я хочу получить это: (* * * * *).

Как я могу это сделать?

Ответы [ 4 ]

0 голосов
/ 27 января 2019

Я думаю, вам нужна функция make-list

(make-list 5 '*) => (* * * * *)
0 голосов
/ 17 января 2019

Тестируя, я нашел, как это сделать, используя хвостовую рекурсию:

#lang racket

(define my-build-list
  (lambda (n l)
    (if (zero? n) l (my-build-list (- n 1) (append l (list '*))))))

(my-build-list 5 '())

> '(* * * * *)

Я добавляю этот ответ только в качестве примера того, как сделать это с помощью хвостовой рекурсии.

0 голосов
/ 17 января 2019

Я думаю, вы должны использовать const в этом случае -

#lang racket
(build-list 5 (const '*))
;; => '(* * * * *)

Из документов -

(const v) → procedure?
v : any

Возвращает процедуру, которая принимает любые аргументы (включая ключевые аргументы) и возвращает v.

Примеры -

((const 'foo) 1 2 3)
;; 'foo

((const 'foo))
;; 'foo

Я вижу, вы пытались реализовать свою собственную хвостовую рекурсивную форму. Вот ревизия, в которой не используется дорогостоящая операция append -

(define (my-build-list n proc)
  (let loop ((acc empty)
             (n (sub1 n)))
    (if (< n 0)
        acc
        (loop (cons (proc n) acc)
              (sub1 n)))))

(my-build-list 5 (const '*))
;; '(* * * * *)

(my-build-list 5 identity)
;; '(0 1 2 3 4)
0 голосов
/ 17 января 2019

Лямбда-функция, которую вы передаете, должна принимать один аргумент, который является индексом элемента (как вы можете видеть из сообщения об ошибке: (exact-nonnegative-integer? . -> . any/c)). Это полезно, когда вы пытаетесь создать список, элементы которого различаются в зависимости от позиции индекса. Например, (build-list 5 (lambda (n) n)) производит '(0 1 2 3 4)

В вашем случае аргумент бесполезен, так как список, который вы хотите построить, имеет одинаковое содержимое для всех элементов. Тем не менее, вы все равно должны принять аргумент. То есть используйте (build-list 5 (lambda (n) '*)). Если вы находите это уродливым, есть также thunk*, который является сокращением для создания лямбды, которая принимает все, но игнорирует аргументы. Таким образом, вы также можете написать (build-list 5 (thunk* '*)). Если вы используете #lang racket/base, вам нужно (require racket/function), чтобы использовать thunk*.

...