The biggest takeaway for me was that Haskell got the numerical typeclasses completely wrong. Instead of using different sets of numbers (rational, integer, fractional, etc.) you should use algebraic structures instead. This is what Purescript ended up doing. So the (+) and (*) operations are declared in the “Semiring” type class, (-) is defined in the “Ring” type class, etc. There’s a helpful diagram of the hierarchy on this StackOverflow post: https://stackoverflow.com/questions/37667240/is-there-a-purescript-typeclass-generalizing-integers

Using the algebraic structures brings the numeric operations more in line with the other typeclasses which are based on algebraic structures.

I made a post on the /r/haskell subreddit about avoiding typeclass design mistakes. You might be interested in the post: https://www.reddit.com/r/haskell/comments/7vand6/avoiding_type_class_design_mistakes/

The biggest takeaway for me was that Haskell got the numerical typeclasses completely wrong. Instead of using different sets of numbers (rational, integer, fractional, etc.) you should use algebraic structures instead. This is what Purescript ended up doing. So the (+) and (*) operations are declared in the “Semiring” type class, (-) is defined in the “Ring” type class, etc. There’s a helpful diagram of the hierarchy on this StackOverflow post: https://stackoverflow.com/questions/37667240/is-there-a-purescript-typeclass-generalizing-integers

Using the algebraic structures brings the numeric operations more in line with the other typeclasses which are based on algebraic structures.