Soluzione alternativa per l'implementazione di operazioni su strutture dati doppiamente collegate o circolari in lingue con dati immutabili

10

Mi piacerebbe imparare come creare grafici ed eseguire alcune operazioni locali su di essi in Haskell, ma la domanda non è specifica per Haskell, e invece di grafici potremmo considerare elenchi doppiamente collegati.

Domanda: Quale sarebbe un modo idiomatico o consigliato per implementare una lista doppiamente collegata (o altra struttura di dati doppiamente collegata o circolare) e operazioni su di essa in una lingua che supporta e difende strutture di dati immutabili (Haskell, Clojure, ecc.)? In particolare, come utilizzare gli aggiornamenti sul posto, che sono formalmente vietati dalla lingua?

Posso facilmente immaginare che se alcune operazioni locali vengono eseguite su una lista doppiamente collegata (se un articolo è inserito, ad esempio), potrebbe non essere necessario copiare immediatamente l'intera lista a causa della pigrizia della lingua. Tuttavia, poiché l'elenco è doppiamente collegato, se è modificato in un posto, nessuno dei vecchi nodi può essere utilizzato nella nuova versione dell'elenco e dovrebbero essere in qualche modo contrassegnati, copiati, raccolti in modo prioritario prima o poi . Ovviamente si tratta di operazioni ridondanti se si utilizzerà solo la copia aggiornata della lista, ma aggiungerebbero un "overhead" proporzionale alla dimensione della lista.

Questo significa che per tali compiti i dati immutabili sono semplicemente inappropriati e che i linguaggi dichiarativi funzionali senza supporto "nativo" per i dati mutabili non sono altrettanto validi di quelli imperativi? O c'è qualche soluzione complicata?

P.S. Ho trovato alcuni articoli e presentazioni su questo argomento in Internet, ma ho avuto difficoltà a seguirli, mentre penso che la risposta a questa domanda non dovrebbe richiedere più di un paragrafo e forse un diagramma ... Voglio dire, se non c'è soluzione "funzionale" a questo problema, la risposta probabilmente è "usa C". Se ce n'è uno, allora quanto può essere complicato?

Domande correlate

Citazioni pertinenti

Purely functional programming languages allow many algorithms to be expressed very concisely, but there are a few algorithms in which in-place updatable state seems to play a crucial role. For these algorithms, purely-functional languages, which lack updatable state, appear to be inherently inefficient ([Ponder, McGeer and Ng, 1988]).

- John Launchbury e Simon Peyton Jones, Thread di stato funzionale pigro (1994), anche John Launchbury e Simon Peyton Jones, Stato in Haskell ( 1995). Questi documenti introducono ST costruttore di tipi monadici in Haskell.

    
posta Alexey 16.12.2015 - 17:15
fonte

2 risposte

5

Potrebbero esserci altre efficienti strutture di dati immutabili che si adattano al tuo particolare compito, ma non sono così generiche come una lista doppiamente collegata (che sfortunatamente è soggetto a bug di modifica simultanea a causa della sua mutevolezza). Se specifichi il tuo problema in modo più ristretto, è probabile che tale struttura venga trovata.

La risposta generale per (relativamente) attraversamento economico di strutture immutabili è obiettivi. L'idea è che puoi conservare solo abbastanza informazioni per ricostruire una struttura immutabile modificata dalle sue parti non modificate e il pezzo attualmente modificato e spostarsi su di esso su un nodo adiacente.

Un'altra utile struttura è una chiusura lampo . (La parte divertente è che la firma del tipo per una cerniera obiettivo è una derivata matematica di una firma di tipo della struttura.)

Ecco alcuni link.

risposta data 16.12.2015 - 17:51
fonte
2

Haskell non impedisce l'uso di strutture dati mutabili. Sono strongmente scoraggiati e resi più difficili da utilizzare a causa del fatto che le parti del codice che li utilizzano devono alla fine restituire un'azione IO (che alla fine deve essere associata all'azione IO restituita dalla funzione principale), ma ciò non rendere impossibile l'utilizzo di tali strutture se ne hai davvero bisogno.

Suggerirei di indagare sull'uso della memoria transazionale del software come soluzione. Oltre a fornire un modo efficiente per implementare strutture mutevoli, fornisce anche garanzie molto utili per la sicurezza del thread. Vedi la descrizione del modulo al link e la panoramica del wiki su link .

    
risposta data 19.12.2015 - 14:20
fonte