I made a function as follows:
pen :: (a -> b) -> (b -> a) -> (b -> b) -> a -> a
pen conv rev app = rev . app . conv
which is used as follows:
pen read show (\x -> x + 1) "5"
"6"
I am quite new to Haskell, and I am wondering if a function like this exists in the Haskell standard library and what it is called, as I can't find it on Hoogle.
I'm also assuming there is some way to achieve this without (a -> b) -> (b -> a) -> ... and just having a single bijective function, but I'm also not sure how to do this.
Cheers!
I think the most standard name for a general version of this function is dimap
. It doesn't show up in a Hoogle search, unfortunately, since Hoogle lacks support for instances involving (->)
.
Anyway, dimap
is a type class method (for the Profunctor
class), so it's more general than what you want (the same way fmap
would be more general than what someone looking for map
actually wants). Specialized to the Profunctor
instance for functions, it's still more general than you want, as it allows an arbitrary transformation of its input and output arguments to any types, so its type signature specialized to functions is:
dimap :: (a -> b) -> (c -> d) -> (b -> c) -> (a -> d)
which can obviously be be further specialized to the function pen
that you want:
dimap :: (a -> b) -> (b -> a) -> (b -> b) -> (a -> a)
It's not in base
, but it's included in the lens
package or in the standalone profunctors
package:
> import Data.Profunctor -- from "profunctors"
> dimap read show (\x -> x + 1) "5"
"6"
Haskell functions of type a -> b
can't be "bijective" obviously, but if you use the lens
package, an Iso
represents a bijective function.
You can define an Iso
from a function and its inverse by writing:
> import Control.Lens
> showRead = iso show read
To apply a function using this Iso
as a wrapper/unwrapper, you can use the Lens function under
:
> under showRead (+1) "5"
"6"
I guess it's worth noting that showRead
maybe isn't a great Iso
(i.e., isn't fully law-abiding), since show
and read
aren't perfect inverses. (That is, some show
instances produce values that can't be read
back to reproduce the value.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With