I don't think I understand type classes. I'd read somewhere that thinking of type classes as "interfaces" (from OO) that a type implements is wrong and misleading. The problem is, I'm having a problem seeing them as something different and how that is wrong.
For example, if I have a type class (in Haskell syntax)
class Functor f where
fmap :: (a -> b) -> f a -> f b
How is that different than the interface [1] (in Java syntax)
interface Functor<A> {
<B> Functor<B> fmap(Function<B, A> fn)
}
interface Function<Return, Argument> {
Return apply(Argument arg);
}
One possible difference I can think of is that the type class implementation used at a certain invocation is not specified but rather determined from the environment -- say, examining available modules for an implementation for this type. That seems to be an implementation artifact that could be addressed in an OO language; like the compiler (or runtime) could scan for a wrapper/extender/monkey-patcher that exposes the necessary interface on the type.
What am I missing?
[1] Note the f a
argument has been removed from fmap
since given it's an OO language, you'd be calling this method on an object. This interface assumes the f a
argument has been fixed.