Hacker News new | comments | ask | show | jobs | submit login
Counterexamples of Type Classes (functorial.com)
59 points by michaelsbradley on Dec 15, 2015 | hide | past | web | favorite | 8 comments



One effect of such counterexamples is that they lead to the kind of single-method type classes shown in the article; at which point, a type class is essentially a shorthand synonym for that method's signature. This kind of proliferation fits interestingly into the arguments given in http://www.haskellforall.com/2012/05/scrap-your-type-classes...

Of course, type classes still offer a couple of extra niceties, e.g. that type class instances can be inferred whilst extra arguments generally can't, and that instances are globally consistent (this is important for `Set`, which the article also mentions is a counterexample to `Functor`). Still, type classes seem to appear less and less elegant as time goes on (e.g. compare their use in dependently typed languages).

I'm optimistic though, as that indicates that we're asking questions and setting expectations of our systems above and beyond what was common 20 years ago.


A typeclass should indicate some semantic relationship between its instances, so IMO they do provide a safe version of ad-hoc polymorphism. You shouldn't have to name the (type, operation) pair; the whole point of typeclass coherence is that specifying the type and the operation is enough.

I do think typeclass programming could do with having the same functionality as ordinary programming available. Here in Scala typeclasses are ordinary values (resolved via an implicit mechanism), which enables a lot - though the cost of abandoning global coherence is high.

Ultimately, syntax and conciseness does matter. I don't think anything as verbose as that link has a chance of getting off the ground.


I wouldn't call the "cost of abandoning global coherence" to be "high." Outside of data structures that depend on typeclass instances (like Set), it doesn't especially harm my ability to reason about my or others' code in my experience. And the data structures issue (what happens when I join two Sets with potentially different Order instances) can be solved with Scala's dependent type features I believe.


> And the data structures issue (what happens when I join two Sets with potentially different Order instances) can be solved with Scala's dependent type features I believe.

Not really. There's no way to enforce that each Order has a singleton type which is what you'd need to resolve that.


> Still, type classes seem to appear less and less elegant as time goes on

I think part of the problem is that type classes are so easy to abuse. When you have a problem like e.g. monad transformers, where a) you have a lot of boilerplate code which would be irksome if written out by hand, b) you have laws to make sure the generated code is sensible, and c) your types have exactly one such sensible instance, then classes are very nice. Abuses of type classes exist where any of the three above conditions fail to hold IMO, and a scrap-your-typeclasses approach can be very valuable then.


I think that guy independently re-invented ML-style module-based dispatch.


This stack overflow question has some more nice examples: http://stackoverflow.com/questions/7220436/good-examples-of-...


One example I found of an Applicative which is not a Monad is Const[K: Monoid] - <*> is just monadic plus, but you can't flatMap because there's no way to "get a value out" of it.

This is a good reason to implement traverse in terms of Applicative rather than Monad - foldMap then becomes just a special case of traverse.




Applications are open for YC Summer 2019

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact

Search: