For onlookers, I'd note that Haskell typeclasses are something of a trap for beginners who think they are the way to accomplish object-like coding in Haskell.
Actually, records with functions (closures) inside is usually a better choice: simpler, more flexible, more straightforward.
Of course the resemblance between a vtable and a record of functions is very obvious!
Yup, generally in terms of program structure, when I would make a class in C++/C#/Java, I make a module in Haskell. There’s usually a primary type and some helper types exported, along with functions that form the public interface.
If you need polymorphism you can mostly just reach for parametric polymorphism (generics) and closures. Existential types, in the form of closures, explicit existentially quantified types, or rank-2 universally quantified functions, give you basically the same expressive power as virtual functions—they’re all encodings of the same concept.
Typeclasses are more about the principle of “code to the interface, not the implementation”. For example, using a container through its Functor/Applicative/Monad/Monoid/Traversable/Foldable instances lets you be agnostic to its representation, swap it out for testing/performance, &c.
> when I would make a class in C++/C#/Java, I make a module in Haskell.
This. Group you code logically, expose only what's needed. This also gives the FPer a large part of the "encapsulation" and "group by responsibility" advantages that are often mentioned as pros of OO. Without going down the "implicit state sharing" path.
I assume “object-like coding” just means “a data structure and a set of functions for interacting with it. Are you implying that the “right way” of using Haskell doesn’t do anything like that?
For onlookers, I'd note that Haskell typeclasses are something of a trap for beginners who think they are the way to accomplish object-like coding in Haskell.
Actually, records with functions (closures) inside is usually a better choice: simpler, more flexible, more straightforward.
Of course the resemblance between a vtable and a record of functions is very obvious!