Control.Lens.Iso contains many wonderful functions for lifting Isos into various type arguments of useful abstractions. For example:
mappingfor arbitraryFunctorscontramappingforContravariantfunctorsdimapping,lmappingandrmappingforProfunctorsbimappingforBifunctors
I am looking for the function to lift an Iso into the first argument of a Bifunctor, but it doesn't seem to be there. I am currently defining it thusly:
firsting
:: Bifunctor f
=> AnIso s t a b
-> Iso (f s x) (f t y) (f a x) (f b y)
firsting p = bimapping p (iso id id)
Does this function already exist somewhere, or is bimapping p (iso id id) as good as it gets?
Update
Thanks to your question, the next version of
Control.Lens.Isowill includefirstingandseconding.iso id idlooks a bit ugly. Let's try to take that apart.So you can cut your implementation down to
This is probably the most concise form. If you want to really get to the bare bones, of it, read on.
Inlining the definition of
bimappingand simplifying using
first, you getThis is a particularly clear expression, I think. It uses
withIsoto breakpinto the two functions that make up the isomorphism, usesfirstto lift each of them to apply to the first argument of the bifunctor, and then packages them back up withiso. If the relevant bifunctor has an optimizedfirstthat does something better than can be done withbimap, then this will also be faster than the implementation usingbimapping.Inlining
isogivesFinally, inlining
withIso(digging intoControl.Lens.Internal.Iso, which we probably shouldn't do),By the way, the type signature for
plain, without the redundant context, isThis is exactly the same as