Domanda

Sto imparando lo schema R5RS al momento (da PocketScheme) e trovo che potrei usare una funzione incorporata in alcune varianti di Scheme ma non in tutte:Aggiungere!

In altre parole, modificare in modo distruttivo un elenco.

Non sono tanto interessato al codice vero e proprio quanto alla risposta, quanto a comprendere il processo mediante il quale si potrebbe passare un elenco come funzione (o un vettore o una stringa) e quindi modificarlo.

esempio:

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

Quando utilizzo l'approccio come sopra, devo fare qualcosa del genere (define list (append! foo (bar)) che vorrei qualcosa di più generico.

È stato utile?

Soluzione

La mutazione, sebbene consentita, è fortemente scoraggiata in Scheme.PLT è arrivato addirittura a rimuoverlo set-car! E set-cdr! (sebbene li abbiano "sostituiti" con set-mcar! E set-mcdr!).Tuttavia, una specifica per append! apparso in SRFI-1.Questo append! è un po' diverso dal tuo.Nell'SRFI, l'implementazione Maggio, ma non lo è necessario per modificare le celle contro per aggiungere gli elenchi.

Se vuoi avere un append! questo è garantita per modificare la struttura dell'elenco a cui viene aggiunto, probabilmente dovrai scriverlo tu stesso.Non è difficile:

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

Per mantenere semplice la definizione, qui non è previsto alcun controllo degli errori, ma è chiaro che sarà necessario passare un elenco di lunghezza almeno 1 come a, e (preferibilmente) un elenco (di qualsiasi lunghezza) come b.La ragione a deve essere almeno di lunghezza 1 perché non puoi set-cdr! su una lista vuota.

Dato che sei interessato a come funziona, vedo se riesco a spiegarlo.Fondamentalmente, quello che vogliamo fare è scorrere l'elenco a fino ad arrivare all'ultimo cons coppia, che è (<last element> . null).Quindi vediamo prima se a è già l'ultimo elemento nell'elenco controllato null nel cdr.Se lo è, usiamo set-cdr! per impostarlo sull'elenco che stiamo aggiungendo e abbiamo finito.Altrimenti dobbiamo chiamare my-append! sul cdr Di a.Ogni volta che lo facciamo ci avviciniamo alla fine a.Poiché si tratta di un'operazione di mutazione, non restituiremo nulla, quindi non dobbiamo preoccuparci di formare la nostra lista modificata come valore restituito.

Altri suggerimenti

Meglio tardi che mai per mettere in un paio di 2-3 centesimi su questo argomento ...

(1) Non c'è niente di sbagliato con l'utilizzo delle procedure distruttive nello Schema , mentre c'è un solo riferimento al stucture venga modificato. Così, per esempio, la costruzione di un elenco di grandi dimensioni in modo efficiente, frammentaria attraverso un unico riferimento - e quando completo, facendo che (ora presumibilmente non-essere modificato) Lista noto e indicato da vari referenti

.

(2) Penso che APPEND! dovrebbe comportarsi come APPEND, solo (potenzialmente) in modo distruttivo. E così APPEND! dovrebbero aspettarsi un numero illimitato di liste come argomenti. Ogni lista ma l'ultima sarebbe presumibilmente essere impostato-CDR! 'D a quella successiva.

(3) È possibile definizione di APPEND! è essenzialmente nconc da Mac Lisp e Common Lisp. (E altri lische).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top