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.