SORU
23 NİSAN 2011, CUMARTESİ


lensler, fclabels, yapı erişim ve mutasyon için kütüphane veri-erişimci daha iyi olur

Erişmek için en az üç popüler kütüphaneleri ve kayıtları manipüle alanlar vardır. Benim bildiklerim: veri-erişimci, fclabels ve lensler.

Kişisel veri-erişimci ile başladım ve şimdi onları kullanıyorum. Ancak haskell-cafe son zamanlarda fclabels üstün olmak gibi bir düşüncem yoktu.

Bu nedenle bu üç karşılaştırılması (belki daha fazla) kütüphaneler ilgileniyorum.

CEVAP
24 NİSAN 2011, Pazar


Lensler sağlayan benim bildiğim en az 4 kütüphaneler var.

Lens kavramı için bir şey izomorfik sağlar

data Lens a b = Lens (a -> b) (b -> a -> a)

iki işlevi sağlayan bir alıcı ve bir pasör

get (Lens g _) = g
put (Lens _ s) = s

üç kanunlarına tabi:

Eğer bir şey koyarsanız, o ilk, geri alabilirsiniz

get l (put l b a) = b 

Ve sonra ayarı cevabı değiştirmez bu ikinci

put l (get l a) a = a

Ve üçüncü, iki kez koyarak ikinci koy kazanır bir kez koyarak aynı, ya da daha doğrusu.

put l b1 (put l b2 a) = put l b1 a

Tür sistemi Kendin emin olmanız gerekir bu yüzden sizin için bu yasaları kontrol etmek için yeterli değildir unutmayın, kullandığınız ne olursa olsun.

Bu kütüphanelerin çoğu da üstüne ekstra combinators bir sürü sağlamak, ve genellikle şablon çeşit makine otomatik olarak basit bir kayıt türlerinin alanlar için lens üretmek için haskell.

Bunu unutmayın, farklı uygulamaları dönebiliriz:

Uygulamaları

fclabels

fclabels a :-> b doğrudan yukarıdaki yazın için tercüme edilebilir, çünkü belki de en kolay lens kütüphaneler hakkında gerekçeli. Senin lensler oluşturmak için sağlayan yararlı olan (:->) Category bir örnek sağlar. Ayrıca bir lens burada kullanılan fikrini yaygınlaştırır Point kanunsuz bir tür, ve izomorfizmler ile başa çıkmak için bazı sıhhi tesisat sağlar.

Bir engel kabul fclabels ana paketi içerir şablonu-haskell sıhhi tesisat, yani paket değil Haskell 98, ve bunu da gerektirir (adil olmayan tartışmalı) TypeOperators uzantısı.

veri-erişimci

data-accessor fclabels yer, çünkü daha biraz daha popülerHaskell 98. Ancak, iç gösterim seçimleri ağzıma biraz atış yaptı.

Objektif göstermek için kullandığı 28 ** türü, DAHİLİ olarak tanımlanır

newtype T r a = Cons { decons :: a -> r -> (a, r) }

30* *için sonuç olarak, bir objektif değeri, tanımsız bir değer göndermeniz gerekir 'bir' tartışma! Bu inanılmaz derecede çirkin ve geçici bir uygulama olarak beni vurur.

O Henning şablon-haskell tesisat otomatik olarak ayrı bir 'data-accessor-template' paketi. sizin için set oluşturmak için dahil olduğunu söyledi,

Vardır parası olan bir adam gibi büyük seti paketler zaten hırsızlıkları, Haskell 98, ve sağlayan çok önemli Category örnek, eğer sen aldırış etme bu işler böyle yürüyor, bu paket aslında oldukça makul bir seçim.

lensler

Sonraki, bir lens iki devlet monadlar arasında devlet monad bir homomorfizma sağlayabilir gözlemler lenses paketi vardır, doğrudan lensler definininggibiböyle monad kesirler cismi.

Eğer gerçekten kendi lens bir tür sağlamak için rahatsız ederse, rütbe-2 tipi gibi olurdu:

newtype Lens s t = Lens (forall a. State t a -> State s a)

Sonuç olarak, ben daha çok yok gibi bu yaklaşım, olarak gereksiz yere yanks sen Haskell 98 (bir tür sağlamak için lens soyut olarak) ve yoksun bırakır seni Category örneğin lens, hangisi izin oluştur onlarla .. Uygulanması da çok parametre türü sınıflar gerektirir.

Not, diğer objektif kütüphaneler, burada bahsedilen bazı kombinatorik sağlamak veya aynı devlet odaklı etki sağlamak için kullanılabilir, hiçbir şey bu şekilde doğrudan lens kodlama ile elde edilir.

Ayrıca, yan koşulları başlangıçta belirtilen gerçekten bu şeklinde güzel bir ifade yok. 'Fclabels' bu otomatik kayıt türü doğrudan ana paketi için lensler oluşturmak için şablon-haskell yöntemi sağlar.

Category örneği, Barok kodlama ve ana paketi içinde şablonu-haskell şartı eksikliği nedeniyle, bu benim en sevdiğim uygulama.

veri-lens

[Edit: 1.8.0, bu veri-objektif] comonad-transformers paketinden taşındı

data-lens paket Store comonad açısından lensler sağlar.

newtype Lens a b = Lens (a -> Store b a)

nerede

data Store b a = Store (b -> a) b

Genişletilmiş eşdeğerdir bu

newtype Lens a b = Lens (a -> (b, b -> a))

Dışarı alıcı tarafından yaygın argüman ve bir çift eleman alma sonucu oluşan geri ayarlayıcı ve yeni bir değer geri koymak için bir ayarlayıcı faktoring olarak görüntüleyebilirsiniz. Bu fazla hesaplama yararına 'pasör' burada geri dönüşüm bazı iş almak için kullanılan değeri, yapmak için daha verimli bir 'değiştirme' operasyonu daha fclabels tanımı, özellikle erişenleri vardır zincirleme.

Orada da güzel bir teorik gerekçe için bu temsili, çünkü alt 'Objektif' değerlerini karşılamak 3 yasa belirtti Başlangıçta bu tepki tam olarak bu lens için hangi sarılmış işlevi bir 'comonad coalgebra' için mağaza comonad. Bu lens güzel pointfree 2 eşdeğerleri aşağı l 3 kıllı Kanun dönüştürür:

extract . l = id
duplicate . l = fmap l . l

Bu yaklaşım ilk olarak kaydetti ve O'Connor Functor is to Lens as Applicative is to Biplate: Introducing Multiplate Ç Russell açıklanan ve blogged about based on a preprint Jeremy Gibbons tarafından yapıldı.

Ayrıca Data.Map gibi lensler kesinlikle ve kaplar için bazı hisse senedi lensler ile çalışmak için combinators, bir dizi içerir.

Yani lens data-lens forma Category (aksine lenses paketi), Haskell 98 (aksine fclabels/lenses), aklı başında (aksine arka uç data-accessor) sağlamak ve daha verimli bir şekilde yerine getirilmesi, data-lens-fd sağlar işlevselliği için çalışan MonadState için isteyenler için adım dışında Haskell 98 ve şablonu-haskell makine artık kullanılabilir) data-lens-template.

Güncelleme 6/28/2012: Diğer Lens Uygulama Stratejileri

İzomorfizma Lensler

Diğer iki lens kodlamaları dikkate değer vardır. İlk güzel teorik bir şekilde alanın değerini bir yapısı kırmak için bir yol olarak objektif bir görünüm verir, ve 'her şey'.

İzomorfizmler için bir tür verildi

data Iso a b = Iso { hither :: a -> b, yon :: b -> a }

geçerli üyeler* *57 yon . hither = id memnun gibi

Bir lens ile temsil edebiliriz:

data Lens a b = forall c. Lens (Iso a (b,c))

Bu öncelikle lens anlamı hakkında düşünmek için bir yol olarak yararlıdır, ve diğer lensler açıklamak için akıl bir araç olarak kullanabiliriz.

van Laarhoven Lensler

Kullanarak lens (.) ve id, Category bir örneği olmadan bile oluşmuş olabilir böyle bir model yapabiliriz

type Lens a b = forall f. Functor f => (b -> f b) -> a -> f a

bizim için lens türü olarak.

Sonra bir lens tanımlama kadar kolaydır:

_2 f (a,b) = (,) a <$> f b

ve fonksiyon bileşimi lens kompozisyon olduğunu kendiniz de doğrulayabilirsiniz.

Son zamanlarda sadece bu imza yaygınlaştırarak generalize van Laarhoven lenses alan türlerini değiştirebilir lens aileler için daha ne kadar, yazdım

type LensFamily a b c d = forall f. Functor f => (c -> f d) -> a -> f b

Bu lensler hakkında konuşmak için en iyi yolu rank 2 polimorfizmi kullanmak için talihsiz bir sonucu da var, ama lens tanımlarken imza doğrudan kullanmanıza gerek yok.

_2 yukarıda tanımlı Lens aslında LensFamily.

_2 :: Functor f => (a -> f b) -> (c,a) -> f (c, b)

Alıcılar, belirleyiciler, kıvrımlar ve dolaşımları da dahil olmak üzere lensler, lens aileler ve diğer genellemeler içeren bir kütüphane yazdım. lens paket olarak hackage mevcuttur.

Yine, büyük bir avantajı da bu yaklaşım olduğunu kütüphane bakıcılarına olabilir aslında oluşturmak lensler bu tarz kütüphaneler olmadan ödemeden herhangi bir objektif kütüphane bağımlılık ne olursa olsun, sadece tedarik fonksiyonları yazın Functor f => (b -> f b) -> a -> f a, kendi özel tip 'a' ve 'b'. Bu büyük ölçüde kabul maliyeti düşürür.

Aslında bu paket yeni lensler tanımlamak için kullanmaya gerek yok, çok baskı kütüphaneye 98 Haskell tutma konusunda benim daha önceki endişeler sürüyor.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Ciaran Blumenfeld

    Ciaran Blume

    20 NİSAN 2009
  • FullMag

    FullMag

    15 ŞUBAT 2007
  • pucksz

    pucksz

    24 Mart 2006