Saya ingin belajar cara membuat grafik dan melakukan beberapa operasi lokal pada mereka di Haskell, tetapi pertanyaannya tidak spesifik untuk Haskell, dan alih-alih grafik kita dapat mempertimbangkan daftar yang ditautkan ganda.
Pertanyaan: Apa yang akan menjadi cara idiomatis atau yang direkomendasikan untuk menerapkan daftar yang ditautkan ganda (atau struktur data ganda yang ditautkan ganda) dan operasinya dalam bahasa yang terutama mendukung dan mengadvokasi untuk struktur data yang tidak dapat diubah (Haskell, Clojure, dll.) ? Secara khusus, bagaimana cara menggunakan pembaruan di tempat, yang secara resmi dilarang oleh bahasa tersebut?
Saya dapat dengan mudah membayangkan bahwa jika beberapa operasi lokal dilakukan pada daftar yang ditautkan ganda (jika item dimasukkan, misalnya), mungkin tidak perlu menyalin seluruh daftar segera karena kemalasan bahasa. Namun, karena daftar ini ditautkan dua kali lipat, jika dimodifikasi di satu tempat, tidak ada node lama yang dapat digunakan dalam versi baru daftar, dan mereka perlu ditandai, disalin, dikumpulkan dengan cepat atau lambat . Jelas ini adalah operasi yang berlebihan jika hanya salinan daftar yang diperbarui yang akan digunakan, tetapi mereka akan menambahkan "overhead" sebanding dengan ukuran daftar.
Apakah ini berarti bahwa untuk tugas-tugas seperti itu data yang tidak dapat diubah sama sekali tidak sesuai, dan bahasa deklaratif fungsional tanpa dukungan "asli" untuk data yang dapat berubah tidak sebagus yang imperatif? Atau, adakah solusi yang rumit?
PS Saya telah menemukan beberapa artikel dan presentasi mengenai hal ini di Internet tetapi mengalami kesulitan untuk mengikutinya, sementara saya berpikir bahwa jawaban untuk pertanyaan ini tidak boleh lebih dari satu paragraf dan mungkin diagram ... Maksud saya, jika ada tidak ada solusi "fungsional" untuk masalah ini, jawabannya mungkin adalah "gunakan C". Jika ada, maka seberapa rumitkah itu?
Pertanyaan-pertanyaan Terkait
+ Msgstr "Struktur data dalam pemrograman fungsional" . Pertanyaan khusus saya tentang menggunakan pembaruan di tempat alih-alih alternatif yang tidak efisien tidak dibahas di sana.
"Mutasi Internal Struktur Data Persisten" . Di sana penekanannya tampaknya pada implementasi tingkat rendah dalam bahasa yang tidak ditentukan, sementara pertanyaan saya adalah tentang pilihan bahasa yang tepat (fungsional atau sebaliknya) dan tentang kemungkinan solusi idiomatik dalam bahasa fungsional.
Kutipan yang relevan
Bahasa pemrograman yang murni fungsional memungkinkan banyak algoritma untuk diekspresikan dengan sangat singkat, tetapi ada beberapa algoritma di mana keadaan yang dapat diupdate tampaknya memainkan peran penting. Untuk algoritma ini, bahasa murni fungsional, yang tidak memiliki status yang dapat diupdate, tampaknya secara inheren tidak efisien ( [Ponder, McGeer dan Ng, 1988] ).
- John Launchbury dan Simon Peyton Jones, thread status fungsional Lazy (1994), juga John Launchbury dan Simon Peyton Jones, State in Haskell (1995). Makalah ini memperkenalkan ST
konstruktor tipe monadik di Haskell.
DiffArray
tipe. Melihat sumber dari diffarray paket, saya melihat 91 kejadian unsafePerformIO
. Sepertinya jawaban untuk pertanyaan saya adalah "ya, tidak, bahasa murni fungsional dengan data tidak dapat diubah tidak cocok untuk menerapkan algoritma yang biasanya mengandalkan pembaruan di tempat".
Map
, IntMap
, atau HashMap
) sebagai storage dan untuk membuat node berisi ID dari node terkait. "Semua masalah dalam ilmu komputer dapat diselesaikan dengan tingkat tipuan yang lain."