Suppose I have a multi-parameter type class
class MyClass a b where
...
foo :: MyClass a b => a -> b
foo = ...
Is it possible to define a custom infix symbol for this relation, so that I can instead write
infixr 1 ?
class a ? b where
...
foo :: a ? b => a -> b
foo = ...
Yes, with TypeOperators
you can give a symbolic name to a class directly:
{-# Language
MultiParamTypeClasses,
TypeOperators #-}
module Example
( type (?)
…
) where
class a ? b where
…
infixr 1 ?
foo :: a ? b => a -> b
foo = …
Or you can make an infix alias for a named class using ConstraintKinds
:
{-# Language
ConstraintKinds,
MultiParamTypeClasses,
TypeOperators #-}
module Example
( type (?)
…
) where
class C a b where
…
type a ? b = C a b
infixr 1 ?
Note that you may need ExplicitNamespaces
for importing this as well, if it’s ambiguous.
Another alternative is an empty subclass, if you expect to extend it with additional constraints, since this tends to be better for inference:
class (C a b) => a ? b
instance (C a b) => a ? b
infixr 1 ?