Control.Lens.Tuple определяет линзы для доступа к элементам кортежей. Например
class Field3 s t a b | s -> a, t -> b, s b -> t, t a -> s where
-- | Access the 3rd field of a tuple.
_3 :: Lens s t a b
-- >>> (1,2,3)^._3
-- 3
--
-- >>> _3 .~ "hello" $ (1,2,3)
-- (1,2,"hello")
Сеттер _3 .~
возвращает кортеж с измененным третьим элементом другого типа в этом примере.
Для класса Field3
есть экземпляры, определенные для кортежей с тремя или более элементами. Не для пар / двух человек, потому что что получит геттер?
Но если установщик может изменить тип n-го элемента, то почему он не может изменить тип на другой набор кортежей?
-- >>> _3 .~ "hello" $ (1,2)
-- (1,2,"hello")
То есть установщик _3 .~
устанавливает третий элемент, расширяя его в два раза.
instance Field3 (a,b) (a,b,c') Dummy c' where
_3 k ~(a,b) = k undefined <&> \c' -> (a,b,c')
, в котором Dummy
и undefined
- это некоторый тип и значение заполнителя для несуществующего третьего элемента входящего двойника.
После расширения до арности 3 объектив _3
работает как обычно; объективы _1, _2
подчиняются законам об объективах на всем протяжении.
Q1. Будет ли это работать для сеттера?
(конечно, для обновления не будет / over
)
Q2. Если да, то есть ли способ сделать его неправильно напечатанным, чтобы попытаться view
использовать несуществующий третий элемент?
Q3. Если сеттер не будет работать, может ли быть оператор extend
, который достигнет эффекта? (Предположительно с использованием другого функтора.)
Возможно, это может быть случай
instance Field3 (a,b) (a,b,c') (a,b) c' where
_3 k ~(a,b) = k (a,b) <&> \c' -> (a,b,c')
Так, что view
вернет странно типизированный результат, а over
потенциально может построить третий элемент из первых двух.