13
Let's say I have a higher order function f :: (a -> b) -> (a -> b). But f only behaves properly if the input function is surjective. Is there anyway to force this to happen in Haskell? For example, I really want f's type signature to be something like:
f :: (Surjective (a -> b)) => (a -> b) -> (a -> b)
But this doesn't work because I don't want all functions of the type a -> b to be declared to be surjective, only some of them. For example, maybe f converts a surjective function into a non-surjective function.
We could wrap the functions in a special data type data Surjective f = Surjective f, and define
f :: Surjective (a -> b) -> (a -> b)
but this would make it difficult to assign multiple properties to a function.
Is there any convenient way to do this in practice? Is this even possible in theory?