Daftar perbedaan dalam pemrograman fungsional

13

Pertanyaan Apa yang baru dalam struktur data murni fungsional sejak Okasaki? , dan jawaban epik jbapple, disebutkan menggunakan daftar perbedaan dalam pemrograman fungsional (sebagai lawan dari pemrograman logika), yang merupakan sesuatu yang baru-baru ini saya minati. Hal ini membuat saya menemukan implementasi daftar perbedaan untuk Haskell. Saya memiliki dua pertanyaan (maafkan saya jika saya harus membuat dua pertanyaan berbeda di StackExchange).

Pertanyaan sederhananya adalah, adakah yang mengetahui pertimbangan akademis tentang daftar perbedaan dalam pemrograman fungsional dan / atau implementasi selain yang ada di perpustakaan Haskell? Jawaban jbapple tidak memberikan kutipan untuk daftar perbedaan (daftar perbedaan dalam pemrograman logika ada di pengetahuan dan dalam beberapa sumber yang saya miliki Around Here Somewhere (TM)). Sebelum menemukan implementasi Haskell saya tidak menyadari bahwa ide itu telah melompat dari logika ke pemrograman fungsional. Memang, daftar perbedaan Haskell adalah sesuatu penggunaan alami fungsi tingkat tinggi dan bekerja sangat berbeda dari yang ada di pemrograman logika, tetapi antarmuka tentu mirip.

Hal yang lebih menarik (dan jauh lebih membingungkan) yang ingin saya tanyakan adalah apakah batas atas asimtotik yang diklaim untuk pustaka daftar perbedaan Haskell tersebut tampaknya benar / masuk akal. Kebingungan saya mungkin karena saya kehilangan sesuatu tentang yang jelas tentang kompleksitas alasan dengan kemalasan, tetapi batas yang diklaim hanya masuk akal bagi saya jika penggantian atas struktur data yang besar (atau pembentukan penutupan, atau pencarian variabel, atau sesuatu ) selalu membutuhkan waktu yang konstan. Atau "tangkapan" semata-mata karena tidak ada batasan waktu berjalan untuk "kepala" dan "ekor" justru karena operasi-operasi itu mungkin harus melalui tumpukan perhitungan / pergantian yang ditangguhkan secara sewenang-wenang?

Rob Simmons
sumber
1
Pada awalnya saya bingung dengan "bahasa pemrograman fungsional (sebagai lawan dari bahasa pemrograman fungsional)", tetapi apakah Anda bermaksud menulis "(sebagai lawan dari bahasa pemrograman logika)"?
Tsuyoshi Ito
Oh oops - ya, itu yang saya maksud, sudah diperbaiki sekarang.
Rob Simmons
Pertanyaan kedua tampaknya lebih tepat pada Stack Overflow bagi saya tetapi, sekarang setelah Anda bertanya di sini, mungkin lebih baik menunggu untuk melihat apakah seseorang dapat menjawab di sini. Secara pribadi saya tidak dapat menemukan alasan untuk meragukan batasan yang diklaim dari membaca kode sumber, tetapi saya belum mengikuti alasan Anda untuk meragukannya, dan juga saya mungkin kehilangan sesuatu.
Tsuyoshi Ito

Jawaban:

8

Atau "tangkapan" semata-mata karena tidak ada batasan waktu berjalan untuk "kepala" dan "ekor" justru karena operasi-operasi itu mungkin harus melalui tumpukan perhitungan / pergantian yang ditangguhkan secara sewenang-wenang?

Θ(m)m

O(1) fromList

{-# LANGUAGE NoMonomorphismRestriction #-}

data DL a = Id
          | Cons a
          | Compose (DL a) (DL a)

fromList [] = Id
fromList (x:xs) = Compose (Cons x) (fromList xs)

toList x = help x []
    where help Id r = r
          help (Cons a) r = a:r
          help (Compose f g) r = help f $ help g r

empty = Id

singleton = Cons

cons x = append (singleton x)

append = Compose

snoc xs x = append xs (singleton x)

Θ(n)headtail[a] -> [a]toList

jbapple
sumber
Jadi apa yang Anda dapatkan dari kemalasan adalah hanya meminta dua kali daftar tidak akan melakukan operasi mahal dua kali, yang bagus.
Rob Simmons
@Rob, saya tidak mengerti apa yang Anda maksud dengan itu.
jbapple
Saya pikir poin yang saya coba sampaikan (buruk) ada diilustrasikan oleh contoh ini: Saya memiliki daftar perbedaan yang sangat panjang "xs" yang saya buat dengan berulang kali "mengambil" ke dalam daftar asli. Pertama kali saya memanggil "head xs", saya berharap akan membutuhkan O (n) waktu untuk melakukan perhitungan yang ditangguhkan; Namun, karena perhitungan itu harus mendapatkan memo, panggilan kedua ke "head xs" (untuk "xs" yang sama ) harus memakan waktu O (1).
Rob Simmons
1
Yah, saya setuju dengan itu, tetapi kemalasan yang saya rujuk dalam jawaban saya adalah tentang fromList, yang tidak digunakan dalam snoc atau head. Jadi, betapapun hebatnya, saya bingung dengan "apa" dalam pernyataan Anda "apa yang Anda dapatkan dari kemalasan". Saya akan mengatakan teladan Anda dan saya adalah dua hal yang Anda dapatkan dari kemalasan.
jbapple
Oke - dan klarifikasi itu membantu saya memahami poin Anda sebelumnya dengan lebih baik.
Rob Simmons
11

Ya, batas-batasnya tergantung pada asumsi bahwa komposisi fungsi membutuhkan waktu yang konstan. Pada dasarnya, jika Anda memiliki daftar bergabung:

datatype 'a join = Nil | Cons of 'a * 'a join | Join of 'a join * 'a join

HAI(n)

Neel Krishnaswami
sumber