ubuntuusers.de

Scheme cons fügt Punkt "." ein

Status: Gelöst | Ubuntu-Version: Ubuntu 12.04 (Precise Pangolin)
Antworten |

elostio

Avatar von elostio

Anmeldungsdatum:
2. Februar 2006

Beiträge: 424

Wohnort: Guayaquil

Ich arbeite mich gerade durch "My little Schemer".

Ich versuche gerade eine Funktion zu schreiben die bei:

(insertR 'e 'd '(a b c d f g d h))
=> (a b c d e f g d h)

liefert und bei

(insertR 'e 'f '(a b c d))
=> (a b c d e)

dies ist mein Ansatz:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
(define insertR
    (lambda (new old li)
        (cond
            ((null? li) new)
            (else
                (cons
                    (car li)
                    (cond
                        ((eq? old (car li))
                            (cons new (cdr li)))
                        (else (insertR new old (cdr li)))
                    )
                )
            )
        )
    )
)

funktioniert soweit, nur bekomme ich im 2. oben angeführten Fall:

=> (a b c d . e)

wo kommt der Punkt her?

Hier ist der Code online zum ausprobieren (letzte Funktion): http://repl.it/NED

elostio

(Themenstarter)
Avatar von elostio

Anmeldungsdatum:
2. Februar 2006

Beiträge: 424

Wohnort: Guayaquil

Oh habs gefunden: http://download.plt-scheme.org/doc/html/guide/Pairs__Lists__and_Scheme_Syntax.html

Wenn das letzte Argument keine Liste ist dann fügt cons trotzdem die Argumente zusammen, allerdings mit Punkt dazwischen. Auch ist das Ergebnis dann keine Liste aber zumindestens noch ein Pair.

radoe2

Anmeldungsdatum:
30. November 2006

Beiträge: 243

elostio schrieb:

Ich arbeite mich gerade durch "My little Schemer".

Ich versuche gerade eine Funktion zu schreiben die bei:

(insertR 'e 'd '(a b c d f g d h))
=> (a b c d e f g d h)

liefert und bei

(insertR 'e 'f '(a b c d))
=> (a b c d e)

dies ist mein Ansatz:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
(define insertR
    (lambda (new old li)
        (cond
            ((null? li) new)
            (else
                (cons
                    (car li)
                    (cond
                        ((eq? old (car li))
                            (cons new (cdr li)))
                        (else (insertR new old (cdr li)))
                    )
                )
            )
        )
    )
)

funktioniert soweit, nur bekomme ich im 2. oben angeführten Fall:

=> (a b c d . e)

wo kommt der Punkt her?

Hier ist der Code online zum ausprobieren (letzte Funktion): http://repl.it/NED

Da wird kein "Punkt" eingefügt, sondern du baust eine "unechte Liste", bei der das cdr des letzten Elements nicht nil ist, sondern 'e' in deinem Beispiel. Du baust:

1
2
> (cons 'a (cons 'b 'c))
'(a b . c)

Eine Liste mit drei Element wäre aber:

> (cons 'a (cons 'b (cons 'c '())))
(a b c)

elostio

(Themenstarter)
Avatar von elostio

Anmeldungsdatum:
2. Februar 2006

Beiträge: 424

Wohnort: Guayaquil

@radoe2 vielen Dank für die Erklärung!

ich habe das Problem gelöst indem ich anstatt von

((null? li) new)
((null? li) (list new))

verwende. list new macht soweit ich das verstanden habe nichts anderes als:

cons new ()

radoe2

Anmeldungsdatum:
30. November 2006

Beiträge: 243

elostio schrieb:

Oh habs gefunden: http://download.plt-scheme.org/doc/html/guide/Pairs__Lists__and_Scheme_Syntax.html

Wenn das letzte Argument keine Liste ist dann fügt cons trotzdem die Argumente zusammen, allerdings mit Punkt dazwischen. Auch ist das Ergebnis dann keine Liste aber zumindestens noch ein Pair.

Cons baut *immer* ein Pair. Eine Liste in der Lisp-Welt besteht nunmal aus cons-Zellen (Pairs). Das car jeder Zelle zeigt auf das Datenelement, (z.b. 'a), cdr auf die nächste Zelle oder ist nil wenn es die letzte Zelle ist.

Antworten |