(&&&) for a Getter - Haskell

Welcome to the Functional Programming Zulip Chat Archive. You can join the chat here.

Georgi Lyubenov // googleson78
(&&&) :: (a -> b) -> (a -> c) -> a -> (b, c)
(&&&) f  g x = (f x, g x)

Is there some combinator like this, but for Getters?
I want to be able to write this

sth :: Getter a b -> Getter a c -> Getter a (b, c)

data C = C {int :: Int, string :: String}

data A = A {a :: C}

x :: (Int, String)
x = A (C 5 "str") ^. field @"a" . sth (field @"int") (field @"string")
Lysxia

I doubt there is in the lens library because the implementation has to give up the VL representation.

Georgi Lyubenov // googleson78

this can't be implemented using VL? is there some writeup regarding this somewhere, or is it just a natural consequence of how VL lenses work?

Lysxia

It can be implemented, by moving to the plain function representation with to and view. But at that point, why insist on an optic representation when you're essentially doing function composition? You can try to add it but it will be difficult to argue this passes the Fairbairn threshold.

Lysxia

Though there's lensProduct in case the two parameters happen to be lenses https://hackage.haskell.org/package/lens-4.19.2/docs/Control-Lens-Unsound.html

Asad Saeeduddin

@Georgi Lyubenov // googleson78 I don't know about Getters, but there definitely is something like this for lenses

Asad Saeeduddin

well, maybe definitely is too strong a word, I think there's something like this for lenses, but while I've written and used it I haven't proved the result is a valid lens (although I suspect that it is)

Vladimir Ciobanu

I think it's only unsound if b and c (in your example) are not disjoint, which you can't prove from the type definition. I think that's the only reason it's unsound.

Georgi Lyubenov // googleson78

but for read-only it seems like it should be fine, because (intuitively) there's no problem with "what does it mean to modify non-disjoint lenses at the same time?"