问题
Why is:
(apply (car (list 'xor)) '(#t #t))
application: not a procedure; expected a procedure that can be applied to arguments given: 'xor
(apply (car (list (list 'xor))) '(#t #t))
application: not a procedure; expected a procedure that can be applied to arguments given: '(xor)
(apply (car '(xor #t #t)) (cdr '(xor #t #t)))
application: not a procedure; expected a procedure that can be applied to arguments given: 'xor
How to apply first element of list to rest of list?
回答1:
In your program, 'xor
is a symbol, not a procedure. In the program below, xor
refers to the actual procedure, and is not a symbol -
(apply (car (list xor)) (list #t #t))
; #f
(apply (car (list xor)) (list #t #f))
; #t
Or simply -
(apply xor (list #t #f))
; #t
When you write '(xor #t #t)
, xor
is quoted and turned into symbol -
(car '(xor #t #t))
; 'xor
You can use quasi-quoting `(...)
but you most unquote ,...
anything you don't want converted to a symbol -
(apply (car `(,xor #t #t)) (cdr `(,xor #t #t)))
; #f
(apply (car `(,xor #t #f)) (cdr `(,xor #t #f)))
; #t
Presumably the s-expressions will be constructed elsewhere -
(define sexpr1 (list xor #t #t))
(define sexpr2 (list xor #t #f))
(apply (car sexpr1) (cdr sexpr1)) ;#f
(apply (car sexpr2) (cdr sexpr2)) ;#t
If the s-expressions contain purely quoted datum, you can eval the expression using a namespace.
We add racket/base
to allow for procedure application. The procedure in your program, xor
, is included with racket/bool
-
(define (run-sexpr sexpr)
(parameterize ((current-namespace (make-base-empty-namespace)))
(namespace-require 'racket/base)
(namespace-require 'racket/bool)
(eval sexpr)))
(run-sexpr '(xor #t #t)) ;#f
(run-sexpr '(xor #t #f)) ;#t
Above we eval
the entire s-expression, but this may not be desired. To make the program work, we only need eval
to turn the 'xor
symbol into a meaningful procedure, xor
. This is maybe closest to your original goal -
(define (run-sexpr sexpr)
(parameterize (...)
(...)
(apply (eval (car sexpr)) ;only eval car
(cdr sexpr)))) ;apply cdr verbatim
(run-sexpr '(xor #t #t)) ;#f
(run-sexpr '(xor #t #f)) ;#t
来源:https://stackoverflow.com/questions/61626321/how-to-apply-first-element-of-list-to-rest-of-list