<div dir="ltr">I was trying to think of a way to deal with invertible functions, say if I want to set up a one-to-one mapping from A<->B without having to maintain two sets of functions (and worry about them getting out of sync).<div><br></div><div>So I thought about making an "invertible" function. This is a function that knows it's own inverse, and you can compose them and get the inverses for free. Of course you need to set up the base functions manually, but then after that the composed functions don't have to be maintained separately both ways.</div><div><br></div><div>Below I'm going to include some code, and I have a few questions:</div><div><br></div><div>1) Am I (badly) reinventing the wheel.</div><div>2) Is there otherwise something terrible with this approach.</div><div>3) I ended up wanting a function with signature "f a b -> a -> b". This feels strangly like applicative but not exactly. Am I reinventing the wheel here also or should I be doing this differently?</div><div><br></div><div>Any advise appreciated, the ideone link is here: <a href="https://ideone.com/HlUHUd">https://ideone.com/HlUHUd</a></div><div>But I've also copied the code below:</div><div><br></div><div>---</div><div><br></div><div><div>import Prelude hiding ((.))</div><div>import Control.Category ((.), (<<<), (>>>), Category)</div><div><br></div><div>data InvertibleFunction a b = InvertibleFunction (a -> b) (b -> a)</div><div><br></div><div>instance Category InvertibleFunction where</div><div>  (InvertibleFunction b_c c_b) . (InvertibleFunction a_b b_a) = InvertibleFunction (b_c . a_b) (b_a . c_b)</div><div><br></div><div>inv (InvertibleFunction x y) = InvertibleFunction y x</div><div><br></div><div>add :: (Num n) => n -> InvertibleFunction n n</div><div>add x = InvertibleFunction (+x) (\y -> y - x)</div><div><br></div><div>class KindaApplicative f where</div><div>  (<$>) :: f a b -> a -> b</div><div><br></div><div>instance KindaApplicative InvertibleFunction where</div><div>  (InvertibleFunction f _) <$> x = f x</div><div>  </div><div>main = print $ ((inv (add 2)) <$> 5)</div></div><div><br></div></div>