Struktur data dalam pemrograman fungsional

11

Saat ini saya bermain dengan LISP (terutama Skema dan Clojure) dan saya bertanya-tanya bagaimana struktur data khas ditangani dalam bahasa pemrograman fungsional.

Sebagai contoh, katakanlah saya ingin menyelesaikan masalah menggunakan algoritma pathfinding grafik. Bagaimana seseorang biasanya menggambarkan grafik itu dalam bahasa pemrograman fungsional (terutama tertarik pada gaya fungsional murni yang dapat diterapkan pada LISP)? Apakah saya akan melupakan grafik sama sekali dan menyelesaikan masalah dengan cara lain?

pwny
sumber

Jawaban:

14

Sudah lama sejak saya bekerja di LISP, tetapi seingat saya, struktur dasar non-atom adalah daftar. Yang lainnya didasarkan pada itu. Jadi Anda bisa memiliki daftar atom di mana masing-masing atom adalah sebuah node diikuti oleh daftar tepi yang menghubungkan node ke node lain. Saya yakin ada cara lain untuk melakukannya juga.

Mungkin kira-kira seperti ini:

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

dapat memberikan grafik seperti ini:

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

Jika Anda ingin mendapatkan kemewahan, Anda dapat menambahkan bobot ke dalamnya juga:

(
  (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))
)

Anda mungkin juga tertarik dengan ini: CL-Graph (ditemukan oleh google-mencari frasa "struktur grafik lisp")

FrustratedWithFormsDesigner
sumber
4
Ini agak terlambat, tapi saya pikir saya harus memperingatkan bahwa "Segala sesuatu yang lain didasarkan pada [daftar]" menyesatkan. Umum Lisp, Skema dan Clojure semua memiliki vektor, peta, string, serta struktur / kelas, tidak dibangun di atas daftar; yang kode kita menulis untuk menciptakan mereka umumnya adalah daftar, misalnya (make-array '(2 2): awal-elemen 0), tetapi struktur data tidak diimplementasikan menggunakan daftar.
coredump
3

Bahasa fungsional menangani struktur data dengan cara yang sama seperti bahasa non-fungsional: dengan memisahkan antarmuka dari implementasi, membuat tipe data abstrak.

Anda dapat membuat tipe data abstrak di Lisp. Misalnya, untuk grafik, Anda mungkin menginginkan beberapa fungsi:

(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
  ...)

Setelah Anda membuat antarmuka itu ke grafik, Anda dapat mengimplementasikan struktur data aktual dengan berbagai cara, mungkin mengoptimalkan faktor-faktor seperti efisiensi pemrogram, fleksibilitas, dan efisiensi komputasi.

Kuncinya adalah memastikan bahwa kode yang menggunakan grafik hanya menggunakan antarmuka grafik, dan tidak mengakses implementasi yang mendasarinya. Ini akan membuat kode klien lebih sederhana karena tidak dipisahkan dari implementasi yang sebenarnya.


sumber
2

Yah itu akan tergantung pada apakah grafik Anda diarahkan / tidak diarahkan, tertimbang / tidak berbobot tetapi satu cara untuk mewakili grafik, diarahkan berbobot (yang akan menjadi yang paling umum) adalah dengan peta peta (di Clojure)

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

akan mewakili peta dengan node: a: b dan: c. : a menunjuk ke: b dengan bobot 3 dan: c dengan bobot 4.: b menunjuk ke: a dengan bobot 1.: c tidak menunjuk ke apa pun.

WuHoUnited
sumber
1

Dalam Common Lisp, jika saya perlu mewakili sebuah pohon, saya akan menggunakan salah satu daftar (jika hanya untuk peretasan cepat) atau mendefinisikan kelas pohon (atau struct, tetapi kelas berinteraksi dengan baik dengan fungsi generik, jadi mengapa tidak) .

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

Jika saya memerlukan pohon literal dalam kode, saya mungkin juga akan mendefinisikan make-treefungsi yang mengambil daftar representasi pohon yang saya inginkan dan mengubahnya menjadi pohon objek pohon.

Vatine
sumber
-2

Dalam Haskell daftar adalah struktur data dasar dan jika Anda ingin struktur data yang lebih maju Anda sering menggunakan struktur rekursif seperti pohon adalah null atau node dan dua pohon

data Tree a = Null | Node Tree a Tree  
nist
sumber