建立具有相同n项的列表

时间:2019-01-17 11:29:28

标签: scheme racket

我正在尝试使用Racket函数,该函数将返回包含n个相同项目的列表。

我已经尝试过了:

#lang racket

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

但是我得到了错误:

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

我想得到这个:(* * * * *)

我该怎么办?

4 个答案:

答案 0 :(得分:3)

您传入的lambda函数需要接受一个参数,该参数是元素的索引(如错误消息(exact-nonnegative-integer? . -> . any/c)所示)。当您尝试构建其元素根据索引位置而变化的列表时,此功能很有用。例如,(build-list 5 (lambda (n) n))产生'(0 1 2 3 4)

在您的情况下,该参数没有用,因为您要构建的列表的所有元素都具有相同的内容。但是,无论如何,您都需要接受该参数。也就是说,使用(build-list 5 (lambda (n) '*))。如果您觉得这很丑陋,那么还有thunk*,它是创建可以接受任何内容但忽略参数的lambda的简写。因此,您也可以编写(build-list 5 (thunk* '*))。如果您使用的是#lang racket/base,则需要(require racket/function)才能使用thunk*

答案 1 :(得分:2)

在这种情况下,我认为您应该使用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)

答案 2 :(得分:0)

测试,我发现了如何使用尾部递归来做到这一点:

#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 '())

> '(* * * * *)

我仅将此答案作为使用尾递归的示例。

答案 3 :(得分:0)

我认为您需要函数make-list

Modal