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
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.
Yapı numarası artırma için daha iyi bi...
Nasıl Mac OS X üzerinde MySQLdb (Pytho...
Kütüphane olmadan IE için kontrol etme...
Hangi node.js eş zamanlı görevler için...
Bu iki döngü için zaman ve önbellek pe...