I had a thought to generalise ($)
like Control.Category
generalises (.)
, and I've done so with the code at the end of this post (also ideone).
In this code I've created a class called FunctionObject
. This class has a function ($)
with the following signature:
($) :: f a b -> a -> b
Naturally I make (->)
an instance of this class so $
continues to work with ordinary functions.
But this allows you to make special functions that, for example, know their own inverse, as the example below shows.
I've concluded there's one of three possibilities:
- I'm the first to think of it.
- Someone else has already done it and I'm reinventing the wheel.
- It's a bad idea.
Option 1 seems unlikely, and my searches on hayoo didn't reveal option 2, so I suspect option 3 is most likely, but if someone could explain why that is it would be good.
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 -- 7
print $ inverse (add 2) $ 5 -- 3
ArrowApply
typeclass at downloads.haskell.org/~ghc/latest/docs/html/libraries/base/… – LithoArrowApply
is equivalent toMonad
– Chantal