简体   繁体   中英

Isomorphic `fmap` in Haskell

Does such a thing exist in Haskell's Prelude?

wfmap :: Functor f
      => a
      -> (a -> b)
      -> (b -> a)
      -> (b -> f b)
      -> f a
wfmap x u w g = fmap (w) (g (u x))

In a project I'm working on, I often found myself 'converting' a type to another, process it and 'converting' it back.

Reordering the arguments, as leftaroundabout suggests, allows for a tidier definition:

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

As for library support, lens provides nifty support for isomorphisms . A bit more broadly, as Gurkenglas notes...

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

Without diving into the details of how and why that works, one consequence is that your function might be defined as:

wfmap :: Functor f => (a -> b) -> (b -> a) -> (b -> f b) -> a -> f a
wfmap u w g = (iso u w) g

Or even:

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

wfmap is just (a specialised version of) iso , which gives out a function which can be used to convert an b -> fb function on the isomorphism "destination" to an a -> fa one on the isomorphism "source".

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

GHCi> :t \u w g -> over (mapping (iso u w)) (fmap g)
\u w g -> over (mapping (iso u w)) (fmap g)
  :: Functor f => (s -> a) -> (b -> t) -> (a -> b) -> f s -> f t
GHCi> :t \u w g -> under (mapping (iso u w)) (fmap g)
\u w g -> under (mapping (iso u w)) (fmap g)
  :: Functor f => (s -> a) -> (b -> a1) -> (a1 -> s) -> f b -> f a

Finally, note that iso uw can be replaced by any Iso you might find in the libraries or have predefined elsewhere.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM