Is a typeclass constraint discouraged in a typeclass method?
I know that constraints in data are discouraged in Haskell. For instance,
data Eq b => Bar b = Bar b
is not possible without a deprecated extension. I also hear that even
data Bar b = Eq b => Bar b
is not common and even discouraged. (Is this right BTW?)
Is the same true for constraints in typeclasses ? For instance, is doing something like
class Foo a where
foo :: Eq b => a -> b
discouraged in Haskell as well? Is it commonly seen in real code?
A typeclass method is, from a usage perspective, no different from an ordinary polymorphic function which just happens to have that class as a constraint on one (or more) of in its participant type variables. But there may be other type variables in the signature which need other constraints not supplied by the one class head. Constraints are (usually) necessary for you to be able to implement the function, so, it's certainly reasonable to need constraints on class methods – unlike constraints on data
types, which actually serve no purpose at all (the implementation of a data
is just some data layout, it can't possibly need any methods from any classes†).
However, you can avoid this issue by including the extra constrained type variables in the class head:
class (Eq b) => Foo b a where
foo :: a -> b
Sometimes, this is better than your proposal, but sometimes it's certainly not better, for instance if Foo
has a whole bunch of methods and of these only one is concerned with b
at all. Of course in that case it would also be possible to split off only foo
into a subclass that has b
in its head, and leave the other methods in a class without extra constraints. But having two classes instead of one may also not be so nice.
Therefore, I would consider it perfectly legitimate to add constraints to class methods, if you find yourself in a situation where this is a natural thing to do.
Existing examples of methods which have such constraints are foldMap
, traverse
and lift
. It's not a ubiquitous pattern, but definitely not totally uncommon either.
†This looks a bit different if you consider type/data families, but even then you don't need constraints on data
but just the functions that deal with this data.
上一篇: 我们如何知道类型类是否是一个子类?