Geçerli Sahnede Çokgen indekslerini, Çokgen'de sürüklenen noktanın dizinini saklayabilirim ve her seferinde değiştirebilirim. Ancak bu yaklaşım ölçeklenmez - kompozisyon seviyeleri 5'e ve daha fazlasına gittiğinde, kazan plakası dayanılmaz hale gelir.
Kesinlikle haklısın, kazan plakasının etrafından geçemezsen bu yaklaşım ölçeklendirilmez . Özellikle, küçük bir alt bölüme sahip yepyeni bir Sahne oluşturmak için ısıtıcı plaka değişti. Bununla birlikte, birçok işlevsel dil bu tür iç içe yapı manipülasyonuyla uğraşmak için bir yapı sağlar: lensler.
Lens temelde değişmez veriler için bir alıcı ve ayarlayıcıdır. Bir lens, daha büyük bir yapının bazı küçük kısımlarına odaklanır . Bir lens verildiğinde, onunla yapabileceğiniz iki şey vardır - daha büyük bir yapının değerinin küçük kısmını görüntüleyebilir veya daha büyük bir yapının değerinin küçük kısmını yeni bir değere ayarlayabilirsiniz . Örneğin, listedeki üçüncü öğeye odaklanan bir lensiniz olduğunu varsayalım:
thirdItemLens :: Lens [a] a
Bu tür, daha büyük yapının bir şeyler listesi olduğu ve küçük alt bölüm de bu şeylerden biri olduğu anlamına gelir. Bu lens verildiğinde listedeki üçüncü öğeyi görüntüleyebilir ve ayarlayabilirsiniz:
> view thirdItemLens [1, 2, 3, 4, 5]
3
> set thirdItemLens 100 [1, 2, 3, 4, 5]
[1, 2, 100, 4, 5]
Lenslerin yararlı olmasının nedeni, alıcıları ve ayarlayıcıları temsil eden değerlerdir ve diğer değerlerle aynı şekilde onları soyutlayabilirsiniz. Mercekleri döndüren işlevler yapabilirsiniz, örneğin listItemLens
bir numarayı alıp listedeki öğeyi n
görüntüleyen merceği döndüren bir işlev n
. Ayrıca, lensler edilebilir oluşur :
> firstLens = listItemLens 0
> thirdLens = listItemLens 2
> firstOfThirdLens = lensCompose firstLens thirdLens
> view firstOfThirdLens [[1, 2], [3, 4], [5, 6], [7, 8]]
5
> set firstOfThirdLens 100 [[1, 2], [3, 4], [5, 6], [7, 8]]
[[1, 2], [3, 4], [100, 6], [7, 8]]
Her mercek, veri yapısının bir seviyesinin üzerinden geçme davranışını kapsar. Bunları birleştirerek, karmaşık yapıların birden fazla seviyesini geçmek için kazan plakasını ortadan kaldırabilirsiniz. Örneğin, supposing sahip bir scenePolygonLens i
o görüşleri i
bir bir Scene Poligon ve inci polygonPointLens n
gördüğünü nth
bir Poligon içinde Noktası, size şöyle bütün bir sahnede yalnızca önemsediğiniz belirli bir noktayı odaklanarak için objektif yapıcısı yapabilirsiniz:
scenePointLens i n = lensCompose (polygonPointLens n) (scenePolygonLens i)
Şimdi bir kullanıcının çokgen 14'ün 3. noktasını tıkladığını ve 10 piksel sağa taşıdığını varsayın. Sahnenizi şu şekilde güncelleyebilirsiniz:
lens = scenePointLens 14 3
point = view lens currentScene
newPoint = movePoint 10 0 point
newScene = set lens newPoint currentScene
Bu lens
, içindeki bir Sahneyi gezmek ve güncellemek için tüm kazan levhalarını içerir , tek yapmanız gereken noktayı değiştirmek istediğiniz şeydir. Bunu lensTransform
bir lensi, bir hedefi kabul eden bir işlevle ve hedefin lens aracılığıyla görünümünü güncellemek için bir işlevle daha da soyutlayabilirsiniz :
lensTransform lens transformFunc target =
current = view lens target
new = transformFunc current
set lens new target
Bu, bir işlevi alır ve işlevi yalnızca görünüme uygulayarak ve yeni bir görünüm oluşturmak için kullanarak karmaşık bir veri yapısında "güncelleyici" haline getirir. Böylece, 14. çokgenin 3. noktasını sağ 10 piksele taşıma senaryosuna geri dönelim, bu şu şekilde ifade edilebilir lensTransform
:
lens = scenePointLens 14 3
moveRightTen point = movePoint 10 0 point
newScene = lensTransform lens moveRightTen currentScene
Ve tüm sahneyi güncellemek için ihtiyacınız olan bu. Bu çok güçlü bir fikirdir ve değer verdiğiniz veri parçalarını görüntüleyen lensler oluşturmak için bazı güzel işlevleriniz olduğunda çok iyi çalışır.
Bununla birlikte, tüm bunlar işlevsel programlama topluluğunda bile oldukça dışarıda. Lenslerle çalışmak için iyi bir kütüphane desteği bulmak zor ve nasıl çalıştıklarını ve iş arkadaşlarınız için faydalarını açıklamak daha da zor. Bu yaklaşımı bir tuz tanesi ile alın.