Czy ktoś mógłby wyjaśnić mi soczewki funkcjonalne? Jest to zadziwiająco trudny temat dla google i nie zrobiłem żadnego postępu. Wiem tylko, że zapewniają podobną funkcjonalność get/set niż w OO.Funkcjonalne soczewki
74
A
Odpowiedz
56
soczewka składa się z dwóch elementów, getter i ustawiających:
data Lens a b = Lens { getter :: a -> b, setter :: b -> a -> a }
Na przykład, może to mieć szkła dla pierwszej i drugiej części pary:
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)
Rzeczywisty wygoda soczewek polega na tym, że komponują się one:
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
I mechanicznie przekształcają się w State
przejścia:
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)
12
Zobacz odpowiedź na pytanie lenses, fclabels, data-accessor - which library for structure access and mutation is better - ma bardzo jasne objaśnienie soczewek.
Ponadto, dokumentacja bibliotek Data.Lenses i fclabel podaje kilka dobrych przykładów ich użycia.
Jest [miłym wstępem do soczewek] (http://www.youtube.com/watch?v=efv0SQNde5Q) przez Edwarda Kmett na YouTube. Przykłady są w Scali, ale nie powinno to być zbyt trudne do naśladowania. – hammar
Yup, próbowałem to obejrzeć, ale mając wystarczająco dużo czasu, gdy jestem nadal czujny, nie jest tak łatwo: P – Masse
@Jochen: Obiektywy tam opisane nie mają wiele wspólnego z soczewkami, o które chodzi. – sclv