Type classes were created as a structured way of expressing “special polymorphism,” which is basically a technical term for overloaded functions. A type class definition looks something like this:
class Foobar a where foo :: a -> a -> Bool bar :: String -> a
This means that when you apply the foo function to some type arguments that belong to the Foobar class, it looks for an implementation foo specific to this type and uses it. This is very similar to the situation with operator overloading in languages such as C ++ / C #, with the exception of more flexible and generalized ones.
Interfaces serve a similar purpose in OO languages, but the basic concept is somewhat different; OO languages come with a built-in concept of type hierarchy, which Haskell simply does not have, which complicates the situation somewhat, because interfaces can include both overloading using subtypes (that is, by calling methods in the corresponding instances, and subtypes that implement the interfaces that make their supertypes) and through flat type-based dispatch (since two classes implementing the interface may not have a common superclass that also implements it). Given the enormous additional complexity introduced by subtypes, I suggest it is more useful to think of type classes as an improved version of overloaded functions in a language without OO.
It is also worth noting that type classes have much more flexible dispatching methods — interfaces usually apply to only one class that implements it, while type classes are defined for a type that can appear anywhere in the signature of class functions. An equivalent of this in OO interfaces would allow the interface to determine how to pass an object of this class to other classes, define static methods and constructors that would choose an implementation based on what type of return is required in the context of the call, define methods that take arguments of the same type, as a class that implements the interface, and various other things that are not broadcast at all.
In short: they serve similar purposes, but the way they work is slightly different, and type classes are much more expressive, and in some cases easier to use because of working with fixed types, and not from parts of the inheritance hierarchy.
CA McCann Aug 04 2018-11-21T00: 00Z
source share