Предположим, у меня есть такой массив: [1, 2, 3, 4]
Как мне изменить только четные значения, используя пакет линз? Я ищу что-то вроде:
filterLens even (+10) $ [1, 2, 3, 4]
=> [1, 12, 3, 14]
Предположим, у меня есть такой массив: [1, 2, 3, 4]
Как мне изменить только четные значения, используя пакет линз? Я ищу что-то вроде:
filterLens even (+10) $ [1, 2, 3, 4]
=> [1, 12, 3, 14]
Prelude Control.Lens> [1, 2, 3, 4] & each . filtered even %~ (+ 10)
[1, 12, 3, 14]
Чтобы найти такие функции, вы можете указать hoogle искать пакет линз, введя «+ линзы» в поле поиска. В этом случае: http://www.haskell.org/hoogle/?hoogle=%2Blens+filter
Ну, если мы посмотрим на тип, который мы хотим
evens :: Lens' [a] [a]
Кажется, что это должен быть действующий объектив, если мы не будем колебаться с длиной сфокусированного списка. Таким образом, относительно легко построить с использованием пар геттера и оседлости.
evens = lens get set where
get (a:b:xs) = b : get xs
get _ = []
set [] xs = xs
set xs [] = xs
set (x:xs) (y:ys) = x:y:set xs ys
Но если мы обратим пристальное внимание на функцию set, мы увидим трудности с реализацией полной filterLens: мы злоупотребляем тем, что знаем точную структуру цели линзы. Общий filterLens должен иметь возможность реконструировать порядок восстановления общего типа, используя только его часть. Для общих типов и предикатов это невозможно или, по крайней мере, трудно автоматизировать.