DEV Community

Discussion on: What the heck is polymorphism?

Collapse
 
jvanbruegge profile image
Jan van Brügge • Edited

Yeah, you can emulate parts of it with ad-hoc polymorphism, but it remains an approximation because type classes are more like interfaces and not like base classes. You can't do something like super.getWeight().

On the other hands interfaces (at least in Java) are not powerful enough to model type classes either. For simple type classes like Semigroup or Monoid this works perfectly:

class Semigroup a where
    (<>) :: a -> a -> a

class Semigroup a => Monoid a where
    mempty :: a

and in Java:

public interface Semigroup<T> {
    T combine(T a, T b);
}

public interface Monoid<T> extends Semigroup<T> {
    T mempty();
}

The problem is the more complicated type classes like Functor or Monad. More specifically the type classes that use higher kinded types. You see above that the a from the Monoid definition is directly used in the type signature. This means it can only have the kind Type. But take the definition of Functor for example:

class Functor f where
    fmap :: (a -> b) -> f a -> f b

The f is not directly used, but it is partially applied to another type. This means that f has kind Type -> Type, ie it is a type constructor. In Java this would mean that you would need a generic generic type, something like this:

public interface Functor<F<?>> {
    <A,B> F<B> fmap(Function<A, B> f, F<A> x);
}

which is not valid Java at all.

Collapse
 
hiasltiasl profile image
Matthias Perktold

Thanks for the detailed answer!

You are right, even though the two concepts overlap a bit, there is quite some mismatch.