Strutture di dati nella programmazione funzionale


11

Attualmente sto giocando con LISP (in particolare Scheme e Clojure) e mi chiedo come vengono trattate le strutture di dati tipiche nei linguaggi di programmazione funzionale.

Ad esempio, supponiamo che vorrei risolvere un problema utilizzando un algoritmo di pathfinding grafico. Come si potrebbe tipicamente rappresentare quel grafico in un linguaggio di programmazione funzionale (principalmente interessato allo stile funzionale puro che può essere applicato a LISP)? Mi dimenticherei del tutto dei grafici e risolverei il problema in qualche altro modo?

Risposte:


14

È passato un po 'di tempo da quando ho lavorato in LISP, ma, per quanto ricordo, la struttura di base non atomica è un elenco. Tutto il resto si basa su questo. Quindi potresti avere un elenco di atomi in cui ogni atomo è un nodo seguito da un elenco di spigoli che collegano il nodo ad altri nodi. Sono sicuro che ci sono anche altri modi per farlo.

Forse qualcosa del genere:

(
  (a (b c)),
  (b (a c)),
  (c (a b d)),
  (d (c))
)

potrebbe dare un grafico come questo:

un <-> b <-> c <-> d
^ ^
| |
+ --------- +

Se vuoi essere sofisticato, puoi aggiungere anche pesi:

(
  (a (b 1.0 c 2.0)),
  (b (a 1.0 c 1.0)),
  (c (a 1.3 b 7.2 d 10.5)),
  (d (c -10.5))
)

Potresti anche essere interessato a questo: CL-Graph (trovato da Google cercando la frase "struttura del grafico lisp")


4
È un po 'tardi, ma penso che dovrei avvertire che "Tutto il resto è basato su [elenco]" è fuorviante. Common Lisp, Scheme e Clojure hanno tutti vettori, mappe, stringhe, nonché strutture / classi, non costruite in cima alle liste; il codice che scriviamo per crearli generalmente è un elenco, ad esempio (make-array '(2 2): iniziale-elemento 0), ma la struttura dei dati non viene implementata usando gli elenchi.
coredump,

3

I linguaggi funzionali trattano le strutture di dati allo stesso modo dei linguaggi non funzionali: separando l'interfaccia dall'implementazione, creando tipi di dati astratti.

È possibile creare tipi di dati astratti in Lisp. Ad esempio, per un grafico, potresti voler un paio di funzioni:

(define (get-vertices graph) ;; gets all the vertices from a graph
  ...)

(define (get-edges graph) ;; gets all the edges from a graph
  ...)

(define (get-weight vertex-from vertex-to) ;; get the weight of a specific vertex
  ...)

Dopo aver creato tale interfaccia su un grafico, è possibile implementare le strutture dati effettive in molti modi diversi, ottimizzando eventualmente fattori quali l'efficienza del programmatore, la flessibilità e l'efficienza computazionale.

La chiave è assicurarsi che il codice che utilizza i grafici utilizzi solo l'interfaccia del grafico e non acceda all'implementazione sottostante. Ciò manterrà il codice client più semplice in quanto disaccoppiato dall'implementazione effettiva.


2

Bene, dipende dal fatto che il tuo grafico sia diretto / non diretto, ponderato / non ponderato, ma un modo per rappresentare un grafico diretto, ponderato (che sarebbe il più generale) è con una mappa di mappe (in Clojure)

{
 :a {:b 3 :c 4} 
 :b {:a 1} 
 :c {}
}

rappresenterebbe una mappa con nodi: a: b e: c. : a indica: b con un peso di 3 e: c con un peso di 4.: b indica: a con un peso di 1.: c non indica nulla.


1

In Common Lisp, se avessi bisogno di rappresentare un albero, utilizzerei un elenco (se fosse solo per un hack rapido) o definire una classe di alberi (o struct, ma le classi interagiscono bene con le funzioni generiche, quindi perché no) .

(defclass tree ()
  ((node :accessor node :initarg :node)
   (children :accessor children :initarg :children)))

Se avessi bisogno di alberi letterali nel codice, probabilmente definirei anche una make-treefunzione che prende una rappresentazione in elenco dell'albero che desidero e lo trasforma in un albero di oggetti albero.


-2

In Haskell l'elenco è la struttura di dati di base e se vuoi strutture di dati più avanzate, spesso usi strutture ricorsive come un albero è nullo o un nodo e due alberi

data Tree a = Null | Node Tree a Tree  
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.