Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to combine lenses in "parallel"

I'm new to the excelent Control.Lens and I'm trying to combine 2 lens in "parallel" (not in sequence) like I would do with `Control.Arrow.&&&).

If I take the example from the lens documentation:

`data Foo a = Foo { _baz :: Int, _bar :: Int, a }

I would like to be able to do stuff like :

>> let foo = (bar &&& baz) .~ (1, 20) $ Foo undefined undefined "FOO"
>> foo ^. (bar &&& baz) 
(1, 20)

I've looked everywhere and I could not find a way to do so. Is that because :

  • (&&&) exist with another name and I missed it.
  • It's useless. I should not need it, therefore nobody bothered implementing it.
  • It's trivial to do in another way (using both or <*>)

Update

&&& can be implemented that way :

(/|\) :: Lens' f a -> Lens' f b -> Lens' f (a, b)
a /|\ b = lens getBoth setBoth where
    getBoth f = (f ^. a, f ^. b)
    setBoth f (v, w) = a .~ v $ f' where
        f' = b .~ w $ f

barz :: Lens' Foo (Int, Int)
barz = bar /|\ baz

However, it needs a type signature which is a bit annoying.

like image 807
mb14 Avatar asked Apr 27 '14 09:04

mb14


People also ask

What is the formula for combination of lenses?

f1 = +9 cm for convex lens, f2 = −19 cm for concave lens. Hence, the total focal length of this combination is +17.1 cm. Problem 2: A distance of 8 cm separates two narrow convex lenses with focal lengths of 12 cm and 17 cm.

What happens when two lenses are combined?

Combination of lenses. When two lenses are used in combination, the first one forms an image that then serves as the object for the second lens. The magnification of the combination is the ratio of the height of the final image to the height of the object.

What happens if more lamps are added to a parallel circuit?

If more lamps are added in the parallel lighting circuits, they will not be reduced in brightness (as it happens only in series lightning circuits). Because voltage is same at each point in a parallel circuit.

What happens when you combine two resistors in parallel?

When you combine two resistors in parallel, current can flow through both resistors at the same time. Although each resistor does its job to hold back the current, the total resistance of two resistors in parallel is always less than the resistance of either of the resistors because the current has two pathways through which to go.

What are the advantages of parallel wiring?

Good to know: 1 Switches and fuses must be connected through line (Live) wire. 2 Connecting electrical devices and appliances like fan, outlet, light bulbs etc in parallel is a prefer way instead of series wiring. 3 Parallel or series-parallel wiring method is more reliable instead of series wiring.

What is the difference between series and parallel wiring?

1 Switches and fuses must be connected through line (Live) wire. 2 Connecting electrical devices and appliances like fan, outlet, light bulbs etc in parallel is a prefer way instead of series wiring. 3 Parallel or series-parallel wiring method is more reliable instead of series wiring.


Video Answer


1 Answers

This combinator is probably impossible to implement. Consider:

> (baz &&& baz) .~ (1,5)

What should this do?

Even a weaker for of the combinator:

(/|\) :: Lens' s a -> Lens' s a -> Traversal' s a
a /|\ b = (a &&& b) . both

would break the laws:

For example, let's look at baz /|\ baz. Since a Traversal is also a Setter, it must also satisfy the Setter laws. Now, take the second setter law:

over (baz /|\ baz) (f . g) = over (baz /|\ baz) f . over (baz /|\ baz) g

Now, we get:

over (baz /|\ baz) (f . g) 
= \(Foo _baz _bar) -> Foo (f . g . f . g $ _baz) _bar

and:

over (baz /|\ baz) f . over (baz /|\ baz) g
= \(Foo _baz _bar) -> Foo (f . f . g . g $ _baz) _bar

Those two are obviously different. The problem arises when the two lenses "overlap", and this is not encoded in the type.

like image 137
bennofs Avatar answered Oct 05 '22 14:10

bennofs