Using AND with the apply function in Scheme

前端 未结 9 909
被撕碎了的回忆
被撕碎了的回忆 2020-12-03 05:26

Why doesn\'t the following work?

(apply and (list #t #t #f))

While the following works just fine.

(apply + (list 1 3 2))


        
相关标签:
9条回答
  • 2020-12-03 05:54

    try this:

    (define list-and (lambda (args) (and (car args) (list-and (cdr args)))))
    

    then you can use apply to list-and!

    0 讨论(0)
  • 2020-12-03 05:55
    (define and-l (lambda x 
        (if (null? x)
            #t
            (if (car x) (apply and-l (cdr x)) #f))))
    

    pleas notice that this is lambda variadic! apply example (and-l #t #t #f)

    or you can use it via apply procedure(as was asked) for example (apply and-l (list #t #t #f))

    both options are ok...

    0 讨论(0)
  • 2020-12-03 05:56

    I've stumbled across the same problem and found an elegant solution in Racket. Since the problem is that "and" is a macro and not a function in order to prevent the evaluation of all its arguments, I've read a little on "lazy racket" and found that "and" is a function in that language. So I came up with the following solution where I just import the lazy and as "lazy-and":

    #lang racket
    (require (only-in lazy [and lazy-and]))
    
    (define (mm)
      (map number? '(1 2 3)))
    
    (printf "~a -> ~a\n" (mm) (apply lazy-and (mm)))
    

    which yields

    (#t #t #t) -> #t
    
    0 讨论(0)
  • 2020-12-03 06:05

    You could also use

    (define (andApply lBoo) (if (not (car lBoo)) #f (if (= 1(length lBoo)) (car lBoo) (andApply (cdr lBoo)))))

    0 讨论(0)
  • 2020-12-03 06:09

    and isn't a normal function because it will only evaluate as few arguments as it needs, to know whether the result is true or false. For example, if the first argument is false, then no matter what the other arguments are, the result has to be false so it won't evaluate the other arguments. If and were a normal function, all of its arguments would be evaluated first, so and was made a special keyword which is why it cannot be passed as a variable.

    0 讨论(0)
  • 2020-12-03 06:11

    If you REALLY wanted to have a function pointer to a function that does and, and you don't mind behavior different than the "real" and, then this would work:

    (define and-l (lambda (a b) (and a b)))
    

    Which you can apply like this:

    (apply and-l (list #t #f))
    

    The two caveats are:

    1. All of the args get evaluated, in violation of the definition of and, which should have shortcutting behavior.
    2. Only two arguments are allowed.
    0 讨论(0)
提交回复
热议问题