
Counterexamples of Type Classes - michaelsbradley
http://blog.functorial.com/posts/2015-12-06-Counterexamples.html
======
chriswarbo
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...](http://www.haskellforall.com/2012/05/scrap-your-type-classes.html)

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.

~~~
lmm
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.

~~~
whateveracct
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.

~~~
lmm
> 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.

------
hesselink
This stack overflow question has some more nice examples:
[http://stackoverflow.com/questions/7220436/good-examples-
of-...](http://stackoverflow.com/questions/7220436/good-examples-of-not-a-
functor-functor-applicative-monad)

------
lmm
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.

