resueltos manejo listas ejercicios drracket scheme

manejo - Usando AND con la función aplicar en Scheme



manejo de listas en scheme (9)

¿Por qué no funciona lo siguiente?

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

Mientras que el siguiente funciona bien.

(apply + (list 1 3 2))

Este parece ser el caso tanto en R5RS como en R6RS?


and no es una función normal porque solo evaluará los pocos argumentos que necesite para saber si el resultado es verdadero o falso. Por ejemplo, si el primer argumento es falso, no importa cuáles sean los otros argumentos, el resultado debe ser falso para que no evalúe los otros argumentos. Si and fuera una función normal, todos sus argumentos se evaluarían primero, por lo que se convirtió en una palabra clave especial por lo que no se puede pasar como una variable.


and es en realidad una macro, cuya definición se describe en el capítulo 4 de R5RS . La notación "sintaxis de biblioteca" en esa página realmente significa que se implementa como una macro.

La Sección 7.3, Tipos de expresiones derivadas da una posible definición de and macro:

(define-syntax and (syntax-rules () ((and) #t) ((and test) test) ((and test1 test2 ...) (if test1 (and test2 ...) #f))))

Dada esta definición, no es posible usarla and como argumento de función para apply .


Si REALMENTE deseaba tener un puntero a una función que funciona y, y no le molesta el comportamiento diferente al "real" y, entonces esto funcionaría:

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

Que puedes aplicar así:

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

Las dos advertencias son:

  1. Todos los argumentos son evaluados, en violación de la definición de y, que debería tener un comportamiento abreviado.
  2. Solo dos argumentos están permitidos.

prueba esto:

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

entonces puedes usar apply para list-and!


(define and-l (lambda x (if (null? x) #t (if (car x) (apply and-l (cdr x)) #f))))

¡súplicas que esto es lambda variadic ! aplicar ejemplo (and-l #t #t #f)

o puede usarlo a través del procedimiento de solicitud (como se solicitó) por ejemplo (apply and-l (list #t #t #f))

ambas opciones están bien ...


Me encontré con el mismo problema y encontré una solución elegante en Racket. Dado que el problema es que "y" es una macro y no una función para evitar la evaluación de todos sus argumentos, he leído un poco sobre "razzear perezoso" y encontré que "y" es una función en ese idioma. Así que se me ocurrió la siguiente solución donde solo importo el perezoso y como "flojo" y "perezoso":

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

cuyos rendimientos

(#t #t #t) -> #t



También podrías usar

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


También me encuentro con este problema jugando con PLT-Scheme 372, he profundizado en el comportamiento de and-syntax, y descubro el siguiente código que funciona como si intuitivamente esperaras (apply and lst) regresar, pero no lo he logrado hecho prueba exhaustiva.

(define (list-and lst) (cond ((null? lst) ''()) ((not (pair? lst)) (and lst)) ((eq? (length lst) 1) (car lst)) (else (and (car lst) (list-and (cdr lst)))) ) ) Welcome to DrScheme, version 372 [3m]. Language: Textual (MzScheme, includes R5RS). > (eq? (and ''()) (list-and ''())) #t > (eq? (and ''#f) (list-and (list ''#f))) #t > (eq? (and ''a) (list-and (list ''a))) #t > (eq? (and ''a ''b) (list-and (list ''a ''b))) #t > (eq? (and ''a ''b ''()) (list-and (list ''a ''b ''()))) #t > (eq? (and ''a ''b ''#t) (list-and (list ''a ''b ''#t))) #t > (eq? (and ''a ''b ''#f) (list-and (list ''a ''b ''#f))) #t

También descubrí otra solución para atrapar la mente . Lo llamo atrapamiento mental porque al principio no sé cómo convertirlo en una función ... Aquí está (solo una demostración de mi idea intuitiva):

Welcome to DrScheme, version 372 [3m]. Language: Textual (MzScheme, includes R5RS). > (eval (cons ''and (list ''''#f ''''#f ''''#t))) #f > (eval (cons ''and (list ''''a ''''b ''''c))) c

Pero más tarde hice una pregunta y obtuve la respuesta aquí: ¿es posible generar (quote (quote var)) o '''' var dynamically? . Con esta respuesta, uno puede convertir fácilmente la idea anterior en una función.

(define (my-quote lst) (map (lambda (x) `'''',x) lst)) (cons ''and (my-quote (list ''a ''b ''c))) => ''(and ''''a ''''b ''''c)