Conclusions
On the one hand, it feels like we covered a lot of material on how Haskell works. On the other hand, it feels like we only scratched the surface. The reason is that Haskell is an extremely flexible language that allows us to build a wide range of abstractions that capture common programming patterns.
We discussed monoids, functors, and monads as abstractions that are integral to programming in Haskell. At the same time, none of these abstractions were built into the language itself. They are defined as part of the standard library in standard Haskell. There exist other powerful abstractions that are offered either as part of the standard library or as part of widely used third-party packages. Probably one of the most extreme example nowadays is the lens library. Lenses, prisms, and traversals are abstractions that support manipulating deeply nested data structures in ways we can only dream of in most other programming languages. For example, we can update all entries in a tree structure that match some condition using a single one-line expression.
Again, the lens library was implemented in plain old Haskell. Its implementation started by looking at the question of how to model setters and getters you may know from object-oriented languages such as Java in a functional way. That led to the derivation of lens laws that actually have their roots in the laws of comonad coalgebras known from category theory, and their generalization then gave us prisms and traversals as means to access more than one data item at a time.
With the tools we discussed here, you can become an effective Haskell programmer who is able to write Haskell code that is at least as effective and often much shorter and elegant than code you could write in Java or C++. To become a true Haskell guru, you never stop learning because the Haskell community comes up with new abstractions all the time, and learning about them takes your programming to the next level. That's true not only if you want to program in Haskell. Ironically, as much as the programming world complains that Haskell needs monads to model even the simplest side effects—without monads, there are no side effects in Haskell—the flexibility they offer seems to have become a point of envy. Thus, there are some efforts to implement monad libraries in Scala, OCaml, and even C++. My point is that some seemingly esoteric abstractions that functional programmers came up with may end up being adopted in other, currently more mainstream, languages. If you're comfortable programming functionally, wrapping your head around those abstractions will be a breeze.