현재 장면에 다각형 인덱스를 저장하고 다각형에 드래그 한 지점의 인덱스를 저장하고 매번 교체 할 수있었습니다. 그러나이 접근법은 확장되지 않습니다-구성 수준이 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]
렌즈가 유용한 이유는 렌즈가 게터와 세터를 나타내는 값 이므로 다른 값과 동일한 방식으로 렌즈 를 추상화 할 수 있기 때문 입니다. 렌즈를 반환하는 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)
이제 사용자가 다각형 14의 점 3을 클릭하고 오른쪽으로 10 픽셀 이동한다고 가정합니다. 다음과 같이 장면을 업데이트 할 수 있습니다.
lens = scenePointLens 14 3
point = view lens currentScene
newPoint = movePoint 10 0 point
newScene = set lens newPoint currentScene
여기에는 Scene 내부를 순회하고 업데이트하기위한 모든 상용구가 포함되어 lens
있으므로 포인트를 변경하려는 것이 전부입니다. 당신은 이것을 추상적 촉진 할 수 lensTransform
렌즈, 대상 및 수용 기능 기능 렌즈를 통해 대상의보기를 업데이트를 :
lensTransform lens transformFunc target =
current = view lens target
new = transformFunc current
set lens new target
이 함수는 함수를 가져 와서 복잡한 데이터 구조에서 "업데이터"로 변환하여 뷰에만 함수를 적용하고 새 뷰를 구성하는 데 사용합니다. 따라서 14 번째 다각형의 3 번째 점을 오른쪽 10 픽셀로 이동하는 시나리오로 돌아가서 다음과 lensTransform
같이 표현할 수 있습니다 .
lens = scenePointLens 14 3
moveRightTen point = movePoint 10 0 point
newScene = lensTransform lens moveRightTen currentScene
그리고 전체 장면을 업데이트하는 데 필요한 전부입니다. 이것은 매우 강력한 아이디어이며 관심있는 데이터를 보는 렌즈를 구성하는 데 유용한 기능이있을 때 매우 효과적입니다.
그러나 이것은 함수형 프로그래밍 커뮤니티에서도 현재 모든 것들이 있습니다. 렌즈 작업을위한 훌륭한 라이브러리 지원을 찾기가 어렵고 렌즈 작동 방식과 동료에게 어떤 이점이 있는지 설명하기가 훨씬 어렵습니다. 소금 한 조각으로이 방법을 사용하십시오.