If I have two lenses:
foo :: Lens\' X Foo
bar :: Lens\' X Bar
Is there a way to construct a product lens:
foobar :: Lens\'
As phadej explained, there's no law-abiding way to do this in general. However, you can do it anyway and warn your users that they'd better be careful only to apply it to orthogonal lenses.
import Control.Lens
import Control.Arrow ((&&&))
fakeIt :: Lens' s x -> Lens' s y -> Lens' s (x,y)
fakeIt l1 l2 =
lens (view l1 &&& view l2)
(\s (x,y) -> set l1 x . set l2 y $ s)
For example:
Prelude Control.Lens A> set (fakeIt _1 _2) (7,8) (1,2,3)
(7,8,3)
Prelude Control.Lens A> view (fakeIt _1 _2) (1,2,3)
(1,2)