Regarding subtype polymorphism, I think you can use type classes to achieve something similar.
For instance, the type class for your Vehicle example would look like:

classVehiclevwheregetWeight::v->Int

Each 'subtype' can then be modelled as an instance of Vehicle that implements the getWeight function accordingly.

Now I'm far from a Haskell expert, so what do you think about this relation between subtype polymorphism and type classes?

You can also view it from the other side: If you want to model a Haskell type class in Java, you would use an interface, i.e. subtype polymorphism.

For instance, if we take the Functor type class with the fmap function, we would introduce a Functor<T> interface with an fmap method. Functor instances would then be modelled as classes that implement the Functor interface.

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:

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:

classFunctorfwherefmap::(a->b)->fa->fb

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:

Thanks for this!

Regarding subtype polymorphism, I think you can use type classes to achieve something similar.

For instance, the type class for your

`Vehicle`

example would look like:Each 'subtype' can then be modelled as an instance of

`Vehicle`

that implements the`getWeight`

function accordingly.Now I'm far from a Haskell expert, so what do you think about this relation between subtype polymorphism and type classes?

You can also view it from the other side: If you want to model a Haskell type class in Java, you would use an interface, i.e. subtype polymorphism.

For instance, if we take the

`Functor`

type class with the`fmap`

function, we would introduce a`Functor<T>`

interface with an`fmap`

method. Functor instances would then be modelled as classes that implement the`Functor`

interface.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:

and in Java:

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: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 atype constructor. In Java this would mean that you would need a generic generic type, something like this:which is not valid Java at all.

Thanks for the detailed answer!

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