Я смотрю Control.Lens
введение видео.
Это заставляет меня задаться вопросом, почему это необходимо для типа Setter
, чтобы обернуть вещи в функторах.
Он (примерно) определяется следующим образом:
type Control.Lens.Setter s t a b = (Functor f) => (a -> f a) -> s -> f t
Скажем, у меня есть данные, называемые Point
, которые определены следующим образом:
data Point = Point { _x :: Int, _y :: Int } deriving Show
Затем я могу написать свой собственный xlens
следующим образом:
type MySetter s t a b = (a -> b) -> s -> t
xlens :: MySetter Point Point Int Int
xlens f p = p { _x = f (_x p) }
И я могу использовать его следующим образом:
p = Point 100 200
xlens (+1) p -- Results in Point { _x = 101, _y = 200 }
Используя Control.Lens
, тот же эффект достигается посредством:
over x (+1) p
где следующие позиции:
x :: Functor f => (Int -> f Int) -> Point -> f Point
over :: Setter Point Point Int Int -> (Int -> Int) -> Point -> Point
Итак, мой вопрос заключается в том, что тот же эффект может быть достигнут более простым способом, почему Control.Lens
обертывает вещи в функторах? Это выглядит излишним для меня, так как мой xlens
делает то же самое, что и Control.Lens
over x
.
Только для записи я также могу связать объективы таким же образом:
data Atom = Atom { _element :: String, _pos :: Point } deriving Show
poslens :: MySetter Atom Atom Point Point
poslens f a = a { _pos = f (_pos a) }
a = Atom "Oxygen" p
(poslens . xlens) :: (Int -> Int) -> Atom -> Atom
(poslens . xlens) (+1) a -- Results in Atom "Oxygen" (Point 101 200)