Isomorphic `fmap` in Haskell

Is there such a thing in Haskell Prelude?

wfmap :: Functor f => a -> (a -> b) -> (b -> a) -> (b -> fb) -> fa wfmap xuwg = fmap (w) (g (ux)) 

In the project I am working on, I often find that I am “converting” a type to another, processing it, and “converting” it back.

+6
source share
1 answer

Reordering the arguments, as leftaroundabout suggests, allows you to define a more precise definition:

 wfmap :: Functor f => (a -> b) -> (b -> a) -> (b -> fb) -> a -> fa wfmap uwg = fmap w . g . u 

Regarding library support, the lens provides excellent support for isomorphisms . A little wider, as Gurkenglas notes ...

Functor f => (b -> fb) -> a -> fa also called Lens' ab and is a central element of the lens library.

Without going into details of how and why this works, one of the consequences is that your function can be defined as:

 wfmap :: Functor f => (a -> b) -> (b -> a) -> (b -> fb) -> a -> fa wfmap uwg = (iso uw) g 

Or even:

 wfmap :: Functor f => (a -> b) -> (b -> a) -> (b -> fb) -> a -> fa wfmap = iso 

wfmap is just a (specialized version) iso that produces a function that can be used to convert the function b -> fb to the "destination" of an isomorphism on a -> fa on the "source" isomorphism.

It is also worth mentioning mapping , which can be used for a slightly different purpose of applying fmap on the other side of isomorphism:

 GHCi> :t \uwg -> over (mapping (iso uw)) (fmap g) \uwg -> over (mapping (iso uw)) (fmap g) :: Functor f => (s -> a) -> (b -> t) -> (a -> b) -> fs -> ft GHCi> :t \uwg -> under (mapping (iso uw)) (fmap g) \uwg -> under (mapping (iso uw)) (fmap g) :: Functor f => (s -> a) -> (b -> a1) -> (a1 -> s) -> fb -> fa 

Finally, note that iso uw can be replaced with any iso that you can find in libraries or predefined elsewhere.

+7
source

Source: https://habr.com/ru/post/1012859/


All Articles