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 calledLens' 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.