Hacker News new | ask | show | jobs
by ergl 3778 days ago
Hmm, I found functors a bit confusing on my first encounter with the language, but I wouldn't call them 'academic'. If you've ever used Haskell typeclasses, they serve almost the same purpose.

In OO land, they're just a way to ensure that an argument satisfies an interface, exposing certain public functions and properties — just like an object in Java has to implement the Comparable interface in order to be sorted in a collection.

2 comments

Functors are modules that depend on another module. This works like a function whose argument is a module with type given by a signature.

There isn't anything exactly analogous in Java. Functor application can introduce new type definitions at compile time and enforce static type safety. You need this so that you can statically require that you can only take unions of sorted collections whose types came from the same ordering module applied to the same ordered set module.

Yes, I know my example isn't perfect, but I've found is a good way of explaining the general concept to people not familiar with ML's module system. Thanks for your explanation though!
Haskell typeclasses are a headache that many Haskell experts eschew.
Wow, really? I learned some Haskell on the side a few years ago, and typeclasses were one of my favorite features. They allowed so much expressiveness from such small building blocks. They seemed like a cornerstone of the language.

I'm surprised to hear they're often eschewed.

Highly abstract and general typeclasses for standard mathematical and algebraic concepts are extremely useful and not eschewed. With them you can do genuinely generic programming in a syntactically convenient way. Examples include: Functor, Applicative, Monad, Num, Floating, Integral, MonadState, MonadReader, Profunctor, Contravariant, ...

Typeclasses which are ad hoc, specific, and typically defined on a per project basis, are much more debatable. If you have the concept of "rendering to the screen" and you have typeclass Renderable with a render method then this is really no better than just writing separate functions for each instance of the Renderable. This isn't genuinely generic programming, it's just symbol overloading.

Hey, you're talking about my library Renderable - and I'm totally up to finding a more idiomatic way to express the problem. It just so happened that type classes were the easiest way to do that.
Ha, sorry, didn't mean to make it sound like I was talking about anything in particular! I just made up that example on the spot. A "Renderable" thing fits into a common pattern where you see typeclasses used in this way.

(Are you talking about this library? https://hackage.haskell.org/package/renderable-0.1.0.0/docs/...

I don't actually see a Renderable class there anyway.)

Ahh - I thought you may have read my articles on HN or Reddit - how self centered of me :)

Yes, there's no 'Renderable' typeclass but there are 'Primitive's. There are no laws that the 'Primitive' typeclass instances must obey but there are associated types that need to be satisfied. I tried to write this without a typeclass and I just couldn't get it to check, so I turned to TypeFamilies to encode the relation ship between types. I'd love to make it more idiomatic though!

[I'd love some feedback if you're so inclined](https://github.com/schell/renderable/blob/master/src/Data/Re...)

I wouldn't say they are eschewed.

Haskell programmers do seem to prefer typeclasses that come equipped with some set of meaningful "laws" that help to reject "unreasonable" instances.

And even without that, they are very useful for data type conversions and the like.