Reputation: 45921
I'm trying to do with Racket a function that will return a list with n identical items.
I have tried this:
#lang racket
(build-list 5 (lambda () '*))
But I get the error:
build-list: contract violation
expected: (exact-nonnegative-integer? . -> . any/c)
given: #<procedure>
I want to get this: (* * * * *)
.
How can I do it?
Upvotes: 2
Views: 656
Reputation: 131
I think you want the function make-list
(make-list 5 '*) => (* * * * *)
Upvotes: 0
Reputation: 135227
I think you should use const
in this case -
#lang racket
(build-list 5 (const '*))
;; => '(* * * * *)
From the docs -
(const v) → procedure?
v : any
Returns a procedure that accepts any arguments (including keyword arguments) and returns v
.
Examples -
((const 'foo) 1 2 3)
;; 'foo
((const 'foo))
;; 'foo
I see you tried implementing your own tail-recursive form. Here's a revision that doesn't use the costly append
operation -
(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)
Upvotes: 2
Reputation: 45921
Testing, I have found how to do it using tail recursion:
#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 '())
> '(* * * * *)
I only add this answer as an example of how to do it using tail recursion.
Upvotes: 0
Reputation: 6502
The lambda function that you pass in needs to accept one argument which is the index of the element (as you can see from the error message: (exact-nonnegative-integer? . -> . any/c)
). This is useful when you are trying to build a list whose elements vary depending on index position. E.g., (build-list 5 (lambda (n) n))
produces '(0 1 2 3 4)
In your case, the argument is useless as the list that you want to build has the same content for all elements. However, you need to accept the argument anyway. That is, use (build-list 5 (lambda (n) '*))
. If you find this ugly, there's also thunk*
which is a shorthand for creating a lambda that accepts anything but ignores arguments. So you can also write (build-list 5 (thunk* '*))
. If you are using #lang racket/base
, you need to (require racket/function)
to use thunk*
.
Upvotes: 3