Fonksiyonel programlamada fark listeleri


14

Sorusu Okasaki beri tamamen fonksiyonel veri yapıları yenilikler? ve jbapple'ın epik yanıtı, son zamanlarda ilgilendiğim bir şey olan fonksiyonel programlamada (mantık programlamanın aksine) fark listeleri kullanılarak belirtildi. Bu , Haskell için fark listesi uygulamasını bulmamı sağladı . Ben iki soru var (Onları StackExchange iki farklı soru yapmak beni affet / düzeltmek).

Basit soru şu ki, Haskell kütüphanesi dışında fonksiyonel programlama ve / veya uygulamalardaki fark listelerinin akademik olarak değerlendirilmesinin farkında olan var mı? jbapple'ın cevabı fark listeleri için bir alıntı yapmadı (mantık programlamasındaki fark listeleri, irfanda ve buralarda bir yerlere (TM) sahip olduğum birkaç kaynakta var). Haskell uygulamasını bulmadan önce fikrin mantıktan işlevsel programlamaya sıçradığını bilmiyordum. Haskell fark listeleri, yüksek dereceli işlevlerin doğal kullanımının bir şeyidir ve mantık programlamadakilerden oldukça farklı çalışır, ancak arayüz kesinlikle benzerdir.

Sormak istediğim daha ilginç (ve çok daha başlı) şey, yukarıda belirtilen Haskell fark listesi kütüphanesi için iddia edilen asimtotik üst sınırın doğru / makul görünüp görünmediğidir . Benim karışıklığım, tembellik ile karmaşıklık akıl yürütme hakkında açık bir şey eksik olduğum için olabilir, ancak iddia edilen sınırlar bana sadece büyük bir veri yapısı (veya kapatma oluşumu veya değişken arama veya bir şey ) üzerinde ikame her zaman sabit zaman alıyorsa mantıklıdır . Ya da "yakalama" basitçe "kafa" ve "kuyruk" için çalışma süresinde kesin bir sınırlama olmadığı için mi? Çünkü bu operasyonlar keyfi bir şekilde ertelenmiş hesaplama / ikame yığınından geçmek zorunda kalabilir mi?


1
İlk başta “fonksiyonel programlama dilleri (fonksiyonel programlama dillerinin aksine)” ile kafam karıştı, ama “(mantık programlama dillerinin aksine)” demek mi istediniz?
Tsuyoshi Ito

Hata! Evet, demek istediğim bu, şimdi düzeltildi.
Rob Simmons

İkinci soru bana Yığın Taşması konusunda daha uygun görünüyor, ancak şimdi burada sorduğunuza göre, birisinin buraya cevap verip veremeyeceğini görmek daha iyi olabilir. Şahsen iddia edilen sınırların kaynak kodunu okumasından şüphe etmek için herhangi bir neden bulamıyorum, ancak onlardan şüphe etmek için mantığınızı takip etmedim ve ayrıca bir şey eksik olabilirim.
Tsuyoshi Ito

Yanıtlar:


9

Ya da "yakalama" sadece "kafa" ve "kuyruk" için çalışma süresinde kesin bir sınırlama olmadığı için mi?

Bence bu aşağı yukarı doğru. DL'ler sadece hızlı oluşturma işlemlerine sahiptir, bu nedenle çiftçilik , burada , DL'yi oluşturmak için kullanılan işlem sayısıdır.Θ(m)m

Bazı temel işlemlerin aşağıdaki işlevsizleştirilmiş versiyonu için tembellik gerektirir , ancak aksi takdirde orijinalde talep edilen karmaşıklık sınırlarını anlamanın basit bir yolu olmalıdır .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)

işlemleri ve bunlar oldukları gibi aynı şekilde uygulanabilir versiyonu kullanılarak .Θ(n)headtail[a] -> [a]toList


Tembellikten elde ettiğiniz şey, bir listenin kuyruğunu iki kez istemenin pahalı işlemi iki kez yapmamasıdır, bu da güzeldir.
Rob Simmons

@Rob, bununla ne demek istediğini anlamıyorum.
jbapple

Sanırım (kötü) yapmaya çalıştığım nokta bu örnekle gösterilmiştir: Orijinal listeye tekrar tekrar "snoc" yaparak yaptığım olağanüstü uzun bir fark listesi "xs" var. İlk kez "kafa xs" dediğimde, O (n) ertelenmiş hesaplama yapmak için zaman alacak umuyoruz; ancak, bu hesaplamanın not edilmesi gerektiğinden, "head xs" ( aynı "xs" için) için ikinci çağrı O (1) zamanını alır.
Rob Simmons

1
Buna katılıyorum, ancak cevabımda bahsettiğim tembellik, snoc veya head'da kullanılmayan fromList ile ilgiliydi. Bu nedenle, bilgiçlikçi olduğu gibi, tembelliğinizden ne elde ettiğiniz “ifadenizdeki” ne ile karıştırdım. Örnek ve benim tembellikten aldığınız iki şey diyebilirim .
jbapple

Tamam - ve bu açıklama önceki noktanızı daha iyi anlamama yardımcı oluyor.
Rob Simmons

12

Evet, sınırlar, fonksiyon kompozisyonunun sabit zaman aldığı varsayımına bağlıdır. Temel olarak, bir katılma listeniz varsa:

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

Birleştirmenin sabit bir zaman olduğu ve bunu bir cons-listesine dönüştürmenin olduğu açıktır . Kapakların olağan temsilini düşünüyorsanız, bunun temel olarak veri tiplerinin normal temsili ile aynı işaretçi temsili olduğunu görebilirsiniz. (Alternatif olarak, bu türü bozuk bir fark listesi olarak da görüntüleyebilirsiniz.)O(n)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.