2010-12-15 14 views
5

Estoy tratando de encontrar la manera de hacer esto utilizando contras:Cómo hacer ((AB) (CD).) En Lisp

((A . B) . (C . D))

donde (A . B) y (C . D) se encuentra en cada célula de contras

he intentado hacer esto (cons (cons 'a 'b) (cons 'c 'd)) pero me da esto:

((A.B) C . D)

también me tr ied esto: (cons (cons 'a 'b) (cons (cons 'c 'd)())) pero me da esto:

((A . B) (C . D))

alguna idea de cómo lograr esto?

+5

El segundo se parece a lo que desea. ¿De qué manera no es adecuado? –

+0

@Anon: El segundo no tiene el punto medio. En realidad, es un valor diferente, porque hay una nula (lista vacía) allí. –

Respuesta

0

No estoy muy seguro de lo que quiere decir ... Estoy de acuerdo con el comentario anterior de que la última línea de su código se asemeja a la primera, con la que se compara.

Aquí hay un recurso general digno para que de todos modos: http://www-2.cs.cmu.edu/~dst/LispBook/

7

Basta con mirar lo que recibe cuando se introduce en un literal ((A . B) . (C . D)):

 
* '((a . b) . (c . d)) 

((A . B) C . D) 

Hay una defined algorithm la impresora Lisp utiliza para imprimir estructuras de datos construidas a partir de pares. Básicamente, nunca se puede obtener un inconveniente que se imprima como un par de puntos dentro de paréntesis cuando es el CDR de otro inconveniente.

Sin embargo, es posible volver a configurar la impresora de modo que se obtiene el comportamiento que está buscando, a través de SET-PPRINT-DISPATCH:

 
(set-pprint-dispatch 'cons 
    (lambda (stream object) 
    (format stream "(~W . ~W)" (car object) (cdr object)))) 
 
* '((a . b) . (c . d)) 

((A . B) . (C . D)) 
* (cons (cons 'a 'b) (cons 'c 'd)) ;The same object 

((A . B) . (C . D)) 

Aunque, a pesar de que sería francamente ser mejor en el largo plazo si te sientes cómodo leyendo el comportamiento predeterminado.

0

Lo que está buscando no es posible debido a cómo se representan las listas en Lisp. Cuando crea una lista, está creando una serie de celdas cons, donde el auto de la celda es el valor de ese elemento en la lista, y el cdr es una referencia a la siguiente celda cons. Su celda deseada, ((A . B) . (C . D)) significa "crear una celda de cons donde el auto es (A . B) y el cdr es (C . D)". Eso es equivalente a una lista donde el primer elemento es (A . B), el segundo elemento es C y el final de la lista es D, o ((A . B) C . D).

+0

Bajé la votación, porque dices que no es posible, ¡entonces explica por qué es equivalente a su primer intento! –

+0

Feria. Estaba diciendo que era imposible conseguir que el intérprete diera la salida que quería. –

15

El primero es lo que quieres. Ellos son equivalentes. Puede verificar la siguiente manera:

1 ]=> (cons (cons 'a 'b) (cons 'c 'd)) 

;Value 11: ((a . b) c . d) 

1 ]=> (car (cons (cons 'a 'b) (cons 'c 'd))) 

;Value 12: (a . b) 

1 ]=> (cdr (cons (cons 'a 'b) (cons 'c 'd))) 

;Value 13: (c . d) 

recordar una lista es una célula contras. El "coche" es el elemento principal de la lista o la primera mitad de la celda cons, y el cdr es el resto de la lista, o el segundo elemento de la celda cons.

Otra forma de comprobar si es equivalente:

1 ]=> '((a . b) . (c . d)) 

;Value 14: ((a . b) c . d) 
+0

Gracias por su ayuda Laurence! Es un buen truco si son equivalentes – darkwingcode