How to apply first element of list to rest of list?

拈花ヽ惹草 提交于 2020-05-16 02:04:07

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!