Pregunta

Estoy aprendiendo R5RS Esquema en el momento (de PocketScheme) y me parece que me podría utilizar una función integrada en algunas variantes de Régimen, pero no todos:Anexar!

En otras palabras destructiva cambio de una lista.

No estoy tan interesado en el código real como una respuesta tanto como la comprensión del proceso por el cual uno puede pasar una lista como una función (o un vector o de cadena) y, a continuación, mutar ella.

ejemplo:

(define (append! lst var)
    (cons (lst var))
)

Cuando yo uso el enfoque como en el anterior, tengo que hacer algo como (define list (append! foo (bar)) lo que me gustaría algo más genérico.

¿Fue útil?

Solución

Mutación, aunque permitió, se desaconseja encarecidamente en el Esquema. PLT incluso fue tan lejos como para eliminar set-car! y set-cdr! (a pesar de que "reemplazados" con set-mcar! y set-mcdr!). Sin embargo, una especificación para append! apareció en SRFI-1 . Este append! es un poco diferente de la suya. En el SRFI, la implementación puede , pero no es es obligatorio para modificar las células contras para anexar las listas.

Si usted quiere tener un append! que es garantizada para cambiar la estructura de la lista que se está anexa a, es probable que tenga que escribirlo usted mismo. No es difícil:

(define (my-append! a b)
  (if (null? (cdr a))
      (set-cdr! a b)
      (my-append! (cdr a) b)))

Para mantener la definición simple, no hay ninguna comprobación de errores aquí, pero está claro que se necesita para pasar de una lista de longitud al menos 1 como a, y (preferiblemente) una lista (de cualquier longitud) como b. La razón a debe tener al menos la longitud 1 es porque no se puede set-cdr! en una lista vacía.

Dado que usted está interesado en cómo funciona esto, voy a ver si puedo explicar. Básicamente, lo que queremos hacer es ir abajo en la lista a hasta llegar a la última pareja cons, que es (<last element> . null). Así que vemos en primer lugar si a ya es el último elemento de la lista mediante la comprobación de null en el cdr. Si es así, utilizamos set-cdr! para establecerlo en la lista que estamos añadiendo, y hemos terminado. Si no es así, tenemos que llamar my-append! en el cdr de a. Cada vez que hacemos esto nos acercamos al final de a. Dado que esta es una operación de mutación, no vamos a devolver nada, por lo que no es necesario preocuparse por la formación de nuestra lista modificada como valor de retorno.

Otros consejos

Mejor tarde que nunca para poner en un par de 2-3 centavos sobre este tema ...

(1) No hay nada malo con el uso de los procedimientos destructivos en el Esquema mientras hay una sola referencia a la stucture ser modificado. Así, por ejemplo, la construcción de una lista grande de manera eficiente, poco a poco a través de una sola referencia - y cuando se haya completado, por lo que la lista (ahora supuestamente no-ser modificado a) conoce y se hace referencia a partir de diversos referentes

.

(2) Creo que APPEND! debe comportarse como APPEND, solamente (potencialmente) destructivamente. Y así APPEND! debe esperar cualquier número de listas como argumentos. Cada lista, pero la última presumiblemente serían D SET-CDR! 'A la siguiente.

(3) La definición anterior de APPEND! es esencialmente NCONC de Mac Lisp y Common Lisp. (Y otros ceceos).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top