누군가 기능 렌즈를 설명해 주시겠습니까? Google에게는 놀랍도록 어려운 주제이며 진전을 이루지 못했습니다. 내가 아는 것은 OO와 비슷한 get / set 기능을 제공한다는 것입니다.
답변
렌즈는 게터와 세터의 두 가지 기능으로 구성됩니다.
data Lens a b = Lens { getter :: a -> b, setter :: b -> a -> a }
예를 들어 한 쌍의 첫 번째 부분과 두 번째 부분에 대한 렌즈가있을 수 있습니다.
fstLens :: Lens (a, b) a
fstLens = Lens fst $ \x (a, b) -> (x, b)
sndLens :: Lens (a, b) b
sndLens = Lens snd $ \x (a, b) -> (a, x)
렌즈의 진정한 편리함은 다음을 구성한다는 것입니다.
compose :: Lens b c -> Lens a b -> Lens a c
compose f g = Lens (getter f . getter g) $
\c a -> setter g (setter f c (getter g a)) a
그리고 그들은 기계적으로 전환으로 State
변환합니다.
lensGet :: MonadState s m => Lens s a -> m a
lensGet = gets . getter
lensSet :: MonadState s m => Lens s b -> b -> m ()
lensSet f = modify . setter f
lensMod :: MonadState s m => Lens s b -> (b -> b) -> m ()
lensMod f g = modify $ setter f =<< g . getter f
(+=) :: (MonadState s m, Num b) => Lens s b -> b -> m ()
f += x = lensMod f (+ x)
답변
질문 렌즈, fclabels, 데이터 접근 자 (구조 접근 및 변형을위한 라이브러리가 더 나은) 에 대한 답변을 참조하십시오. 렌즈에 대한 매우 명확한 설명이 있습니다.
또한 Data.Lenses 및 fclabel 라이브러리에 대한 문서 는 사용되는 몇 가지 좋은 예를 제공합니다.