Funktionslinsen


79

Könnte mir jemand Funktionslinsen erklären? Es ist ein überraschend schwieriges Thema für Google und ich habe keine Fortschritte gemacht. Ich weiß nur, dass sie ähnliche Get / Set-Funktionen bieten wie in OO.


7
Es gibt eine schöne Einführung in Objektive von Edward Kmett auf YouTube. Die Beispiele sind in Scala, aber es sollte nicht zu schwer sein, zu folgen.
— Hammar

Ja, versucht, diese zu sehen, aber genug Zeit zu haben, während ich noch wachsam bin, ist nicht so einfach: P
— Masse

2
@Jochen: Die dort beschriebenen Objektive haben nicht wirklich viel mit den Objektiven zu tun, um die es in dieser Frage geht.
— sclv

3
Hier ist eine schöne Einführung mit Bildern: Objektive in Bildern .
— Debjit

Antworten:


61

Ein Objektiv besteht aus zwei Funktionen, einem Getter und einem Setter:

data Lens a b = Lens { getter :: a -> b, setter :: b -> a -> a }

Zum Beispiel könnten wir Linsen für den ersten und zweiten Teil eines Paares haben:

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)

Der wahre Komfort von Objektiven besteht darin, dass sie Folgendes zusammensetzen:

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

Und sie wandeln sich mechanisch in StateÜbergänge um:

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)

Ihr komponiertes Beispiel hat nicht typecheck. GHC schließt daraus; Objektiv aa -> Objektiv aa -> Objektiv aa
— Masse

Masse: Ich habe versehentlich das fund umgedreht g.
— Apocalisp

Check wird immer noch nicht in a-> c eingegeben. Daraus folgt: Lens ab -> Lens aa -> Lens ab
— Masse

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.