Complementing @sangamon answer, I would like to share my story with the typelevel ecosystem, it may
During my first years learning Scala I found myself searching and searching again and again how to combine two
Maps[String, Int] where for the same keys I wanted the values to be added together.
And the best answer was “Use the
|+| provided by cats (actually scalaz by that time, but whatever)”. However, I always thought that adding a “big” library just for one method was not a good idea (I somewhat now regret that decision, because it wouldn’t have been just one thing).
At some point, I found myself with the necessity to encode some case classes as JSONs and send those through an HTTP endpoint. After googling I found that I could use circe for the first and http4s for the second and that it supported the former out of the box. Nevertheless, that implied using a lot of things like the mysterious
IO monad and of course having cats in scope.
That moment was an inflexion point for me, I joined the gitter channel, started to watch a lot of talks, read the “Scala with cats” book, etc (it was also what later impulses me to answer questions like this one, or in SO; and to contribute to OSS projects. But, that is another story).
In summary, I first just read enough to make the code compile but then I got interested in this functional approach of doing things and wanted to understand even more. I started to use functions provided by cats in my code, i started to use the
IO thing for more things and eventually I switched my main to be using
IOApp. And then the next project I started I used cats-effect right from the beginning.
I agree that you may just add cats to a codebase and use it as a tool-box library (similar to the apache commons / utils in Java). As you become more familiar with the library you will see that you can use it in more places.
Latter, you may look into cats-effect, understand why it exists and which problems does it solves. If you are sold on the ideas of referential transparency & composition and agree that an
IO Monad is a good way to handle side effects, then things like fs2, http4s, refined, shapeless, etc all make sense; since at the end all aim to the same objective, making it easier to reason about your code.