import Prelude hiding ((.), ($)) import Control.Category ((.), Category) class FunctionObject f where ($) :: f a b -> a -> b infixr 0 $ instance FunctionObject (->) where f $ x = f x data InvertibleFunction a b = InvertibleFunction (a -> b) (b -> a) instance Category InvertibleFunction where (InvertibleFunction f f') . (InvertibleFunction g g') = InvertibleFunction (f . g) (g' . f') instance FunctionObject InvertibleFunction where (InvertibleFunction f _) $ x = f $ x inverse (InvertibleFunction f f') = InvertibleFunction f' f add :: (Num n) => n -> InvertibleFunction n n add n = InvertibleFunction (+n) (subtract n) main = do print $ add 2 $ 5 print $ inverse (add 2) $ 5