user1273230
user1273230

Reputation: 29

Haskell sugar for "applyable" class adts containing functions ex. Isomorphisms

Specifically, inspired by J's conjucation operator (g&.f = (f inverse)(g)(f)) I need a way to augment functions with additional information. The obvious way is to use ADT. Something like:

data Isomorphism a b = ISO {FW (a -> b) , BW (b -> a)}
(FW f) `isoApp` x = f x
(BW g) `isoApp` x = g x

But the need for an application function really hurts code readability when most of the time you just want the forward function. What would be very useful is a class:

class Applyable a b c | a b -> c where
    apply :: a -> b -> c

(I think the b could be made implicit with existential quantifiers but I'm not comfortable enough to be sure I wouldn't get the signature wrong)

Now the apply would be made implicit so you could just write

f x

as you would any other function. Ex:

instance Applyable (a -> b) a b where
    apply f x = f x
instance Applyable (Isomorphism a b) a b where
    apply f x = (FW f) x

inverse (Iso f g) = Iso g f

then you could write something like:

conjugate :: (Applyable g b b) => g -> Iso a b -> b -> a
f `conjugate` g = (inverse f) . g . f

Ideally the type signature could be inferred

However, these semantics seem complicated, as you would also need to modify (.) to support Applyable rather than functions. Is there any way to simply trick the type system into treating Applyable datatypes as functions for all normal purposes? Is there a fundamental reason that this is impossible / a bad idea?

Upvotes: 0

Views: 107

Answers (1)

MathematicalOrchid
MathematicalOrchid

Reputation: 62868

As far as I know, function application is possibly the one thing in the entire Haskell language that you cannot override.

You can, however, devise some sort of operator for this. Admittedly f # x isn't quite as nice as f x, but it's better than f `isoApp` x.

Upvotes: 2

Related Questions