あなたが求めているものには、より一般的なバリエーションがあります。
(/\)
:: (Functor f)
=> ((a -> (a, a)) -> (c -> (a, c)))
-- ^ Lens' c a
-> ((b -> (b, b)) -> (c -> (b, c)))
-- ^ Lens' c b
-> (((a, b) -> f (a, b)) -> (c -> f c))
-- ^ Lens' c (a, b)
(lens1 /\ lens2) f c0 =
let (a, _) = lens1 (\a_ -> (a_, a_)) c0
(b, _) = lens2 (\b_ -> (b_, b_)) c0
fab = f (a, b)
in fmap (\(a, b) ->
let (_, c1) = lens1 (\a_ -> (a_, a)) c0
(_, c2) = lens2 (\b_ -> (b_, b)) c1
in c2
) fab
infixl 7 /\
レンズ型シノニムを使用した型シグネチャに注目してください。
Lens' c a -> Lens' c b -> Lens' c (a, b)
2 つのレンズを取り、それらを 1 つのレンズに組み合わせて 1 組のフィールドにします。これはもう少し一般的で、異なるタイプのフィールドを指すレンズを組み合わせる場合に機能します。ただし、2 つのフィールドを別々に変更する必要があります。
人々がこのようなものを探している場合に備えて、このソリューションを公開したかっただけです。