Control.Lens.Iso
contains many wonderful functions for lifting Iso
s into various type arguments of useful abstractions. For example:
mapping
for arbitraryFunctor
scontramapping
forContravariant
functorsdimapping
,lmapping
andrmapping
forProfunctor
sbimapping
forBifunctor
s
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.Iso
will includefirsting
andseconding
.iso id id
looks 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
bimapping
and simplifying using
first
, you getThis is a particularly clear expression, I think. It uses
withIso
to breakp
into the two functions that make up the isomorphism, usesfirst
to 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 optimizedfirst
that does something better than can be done withbimap
, then this will also be faster than the implementation usingbimapping
.Inlining
iso
givesFinally, 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