I read an article which said:
Providing instances for the many standard type-classes [Functors] will immediately give you a lot of functionality for practically free
My question is: what is this functionality that you get for free (for functors or other type-classes)? I know what the definition of a functor is, but what do I get for free by defining something as a functor/other type-class. Something other than a prettier syntax. Ideally this would be general and useful functions that operate on functors/other type-classes.
My imagination (could be wrong) of what free means is functions of this sort: TypeClass x => useful x y = ..
== Edit/Additition ==
I guess I’m mainly asking about the more abstract (and brain boggling) type-classes, like the ones in this image. For less abstract classes like Ord, my object oriented intuition understands.
Functors are simple and probably not the best example. Let’s look at Monads instead:
liftM– if something is a Monad, it is also a Functor whereliftMisfmap.>=>,<=<: you can composea -> m bfunctions for free wheremis your monad.foldM, mapM, filterM… you get a bunch of utility functions that generalize existing functions to use your monad.when,* andguardunless— you also get some control functions for free.join— this is actually fairly fundamental to the definition of a monad, but you don’t need to define it in Haskell since you’ve defined>>=.ErrorTand stuff. You can bolt error handling onto your new type, for free (give or take)!Basically, you get a wide variety of standard functions “lifted” to use your new type as soon as you make it a
Monadinstance. It also becomes trivial (but alas not automatic) to make it aFunctorandApplicativeas well.However, these are all “symptoms” of a more general idea. You can write interesting, nontrivial code that applies to all monads. You might find some of the functions you wrote for your type–which are useful in your particular case, for whatever reason–can be generalized to all monads. Now you can suddenly take your function and use it on parsers, and lists, and maybes and…
* As Daniel Fischer helpfully pointed out,
guardrequiresMonadPlusrather thanMonad.