ฉันสามารถเก็บดัชนีของรูปหลายเหลี่ยมในซีนปัจจุบันดัชนีของจุดลากในรูปหลายเหลี่ยมและแทนที่ทุกครั้ง แต่วิธีการนี้ไม่ได้ปรับขนาด - เมื่อระดับการจัดองค์ประกอบไปถึง 5 และไกลกว่านั้น
คุณพูดถูกวิธีนี้ไม่ได้ปรับขนาดถ้าคุณไม่สามารถเข้าไปในหม้อต้มน้ำได้ โดยเฉพาะแผ่นเกราะสำหรับสร้างฉากใหม่ด้วยการเปลี่ยนแปลงส่วนย่อยเล็กน้อย อย่างไรก็ตามภาษาที่ใช้งานได้หลายตัวมีโครงสร้างสำหรับจัดการกับการจัดเรียงโครงสร้างซ้อนกันเช่นเลนส์
เลนส์นั้นเป็นผู้ทะเยอทะยานและผู้ตั้งค่าสำหรับข้อมูลที่ไม่เปลี่ยนรูป เลนส์มีความสำคัญกับส่วนเล็ก ๆ ของโครงสร้างขนาดใหญ่ รับเลนส์มีสองสิ่งที่คุณสามารถทำได้ด้วย - คุณสามารถดูส่วนเล็ก ๆ ของค่าของโครงสร้างที่มีขนาดใหญ่กว่าหรือคุณสามารถตั้งค่าส่วนเล็ก ๆ ของค่าของโครงสร้างที่มีขนาดใหญ่เป็นค่าใหม่ ตัวอย่างเช่นสมมติว่าคุณมีเลนส์ที่เน้นรายการที่สามในรายการ:
thirdItemLens :: Lens [a] a
ประเภทนั้นหมายถึงโครงสร้างที่ใหญ่กว่าคือรายการสิ่งต่าง ๆ และส่วนย่อยขนาดเล็กเป็นหนึ่งในสิ่งเหล่านั้น ด้วยเลนส์นี้คุณสามารถดูและตั้งค่ารายการที่สามในรายการ:
> view thirdItemLens [1, 2, 3, 4, 5]
3
> set thirdItemLens 100 [1, 2, 3, 4, 5]
[1, 2, 100, 4, 5]
เหตุผลที่เลนส์มีประโยชน์ก็เพราะว่ามันเป็นค่าที่เป็นตัวแทนของ getters และ setters และคุณสามารถนำไปใช้กับค่าอื่น ๆ ได้ คุณสามารถสร้างฟังก์ชั่นที่คืนเลนส์ได้เช่นlistItemLens
ฟังก์ชั่นที่ใช้ตัวเลขn
และส่งคืนเลนส์ที่ดูn
รายการที่อยู่ในรายการ นอกจากนี้ยังสามารถประกอบเลนส์:
> 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]]
แต่ละเลนส์ห่อหุ้มพฤติกรรมสำหรับการสำรวจหนึ่งระดับของโครงสร้างข้อมูล โดยการรวมเข้าด้วยกันคุณสามารถกำจัดหม้อไอน้ำสำหรับการสำรวจโครงสร้างที่ซับซ้อนหลายระดับ ตัวอย่างเช่นสมมติว่าคุณมีscenePolygonLens i
มุมมองที่เป็นi
รูปหลายเหลี่ยมในฉากและpolygonPointLens n
มุมมองที่เป็นnth
จุดในรูปหลายเหลี่ยมคุณสามารถสร้างคอนสตรัคเลนส์เพื่อโฟกัสเฉพาะจุดที่คุณสนใจในฉากทั้งหมดดังนี้:
scenePointLens i n = lensCompose (polygonPointLens n) (scenePolygonLens i)
ตอนนี้สมมติว่าผู้ใช้คลิกจุดที่ 3 ของรูปหลายเหลี่ยม 14 แล้วเลื่อนไปทางขวา 10 พิกเซล คุณสามารถอัปเดตฉากของคุณได้เช่น:
lens = scenePointLens 14 3
point = view lens currentScene
newPoint = movePoint 10 0 point
newScene = set lens newPoint currentScene
สิ่งนี้ประกอบด้วยหม้อไอน้ำทั้งหมดสำหรับการสำรวจและอัปเดตฉากภายในlens
สิ่งที่คุณต้องใส่ใจคือสิ่งที่คุณต้องการเปลี่ยนจุด คุณสามารถสรุปสิ่งนี้ได้ด้วยlensTransform
ฟังก์ชั่นที่รับเลนส์, เป้าหมายและฟังก์ชั่นสำหรับอัพเดทมุมมองของเป้าหมายผ่านเลนส์:
lensTransform lens transformFunc target =
current = view lens target
new = transformFunc current
set lens new target
สิ่งนี้จะใช้ฟังก์ชั่นและเปลี่ยนเป็น "updater" บนโครงสร้างข้อมูลที่ซับซ้อนโดยใช้ฟังก์ชั่นเพื่อดูเฉพาะและใช้เพื่อสร้างมุมมองใหม่ ดังนั้นกลับไปที่สถานการณ์ของการเลื่อนจุดที่ 3 ของรูปหลายเหลี่ยมที่ 14 ไปทางขวา 10 พิกเซลซึ่งสามารถแสดงออกในรูปlensTransform
แบบดังนี้:
lens = scenePointLens 14 3
moveRightTen point = movePoint 10 0 point
newScene = lensTransform lens moveRightTen currentScene
และนั่นคือทั้งหมดที่คุณต้องอัปเดตฉากทั้งหมด นี่เป็นความคิดที่ทรงพลังมากและทำงานได้ดีมากเมื่อคุณมีฟังก์ชั่นที่ดีในการสร้างเลนส์ที่ดูข้อมูลที่คุณสนใจ
อย่างไรก็ตามนี่เป็นสิ่งที่ค่อนข้างออกไปข้างนอกแม้ในชุมชนการเขียนโปรแกรมการทำงาน เป็นการยากที่จะหาการสนับสนุนห้องสมุดที่ดีสำหรับการทำงานกับเลนส์และยังยากที่จะอธิบายว่าพวกเขาทำงานอย่างไรและมีประโยชน์อย่างไรต่อผู้ร่วมงานของคุณ ใช้วิธีนี้ด้วยเม็ดเกลือ