But, all in all, even formulating all this and proving theorems was a good exercise. Good job!
There are at least two formalization of HoTT categories if anybody wants to know more. There's one formalization in HoTT Coq and the formalization as part of the unimath project. Both work heavily with precategories as well as categories in order to formulate some textbook notions without changing all the definitions...
Not sure why you think that. It's a straight-forward construction within this framework and even part of the development.
I’m just beginning to understand all of this category stuff but, as far as I can see, a Haskell function of type
f :: a -> b
f :: a -> Either SomeException a
 http://www.haskellcast.com/episode/013-john-wiegley-on-categ... (skip to “compiling to categories”)
Neither is a particularly satisfying solution if you want to reason about programs, which typically have richer notions of effects. My own recommendation is to embed programs via weakest preconditions (or strongest postconditions as in Chargueraud's characteristic formulas http://www.chargueraud.org/softs/cfml/). This does not allow you to directly evaluate potentially diverging programs, but is far more flexible when reasoning about programs. For example, you can use separation logic to deal with state and concurrency.
If you really want to extract to categories for some reason then I would recommend restricting to concrete categories of presheaves or sheaves - I know of no useful application that doesn't already fit into this framework. Using categories requires you to encode everything into a first-order language which is uneccesarily complicated when working with higher-order functions.
I've seen a video intro  and poked a little bit around the reference manual , but I'm not sure what's "between" basic understanding of the commands and being able to extract a complex verified program.
It all seems to be either the theory (which I mostly grok) or completed projects, not a lot about the engineering details.
...Or does that just not exist?
There's also an annual summer school on the topic which has downloadable videos available: https://www.cs.uoregon.edu/research/summerschool/summer17/
The DeepSpec summer school, however, did lead with a Coq intensive, which was recorded and included in the uploads at https://www.youtube.com/channel/UC5yB0ZRgc4A99ttkwer-dDw .
Software Foundations is a good introduction to Coq and proofs, but overall is quite basic, and it also hides many details of how type theory works, so it's more of a hands on tutorial.
TLA+ is just a tool which basically does its job by exhaustively searching a space of possible solutions trying to find counterexamples. It works in some limited cases but doesn't work generally for any mathematical theorem.
Nope. TLA+ is a rich mathematical formalism, that includes a full-fledged proof assistant. It is, however, focused on verifying software rather than arbitrary mathematical theorems. There is also a model checker for TLA+ that can check your theorems (about finite cases of programs) at the push of a button. In practice, model checkers works in more cases than manual proofs, as manual proofs "fail" much more often, simply by being far too laborious; a model checker would verify in days what may take you months or more to manually prove.
(And for a bit more about Coq to Rust, Program extraction from Coq https://github.com/rust-lang/rfcs/issues/667 )
Is category theory worth studying if I (coming from c++ background) am looking to get into functional languages like Haskell? How common is it actually among Haskell or Lisp programmers to know and utilize concepts from category theory in their programming?
Category theory is the lowest level of functional programming. At this low level you can do some pretty ground-breaking stuff (like the Haskell z3cat library which can apply a SAT solver to a regular Haskell function), but it’s not required, in any way, in order to write great Haskell code, and make use of Haskell as a tool to write applications with very few runtime exceptions.
a) know why some things are done the way they are (in case you're not satisfied with "this works!"), or
b) if you want to find inspiration to write a certain kind of library: Haskell is one of the few languages that has, as I like to call it, "over 50 years of documentation".
To elaborate: a category is a bunch of objects, and functions (morphisms) between the objects. The types in a language like Haskell form a category (called Hask in this case) where the objects are the types and morphisms from one type to another are the functions that go from the former to the latter.
A lot of things done in Haskell are instances of general constructions from category theory applied to Hask. Comfort with these general constructions certainly helps to illuminate many ideas.
For example, the great trifecta of Haskell abstractions comprises three interfaces ("typeclasses") called Functor, Applicative, and Monad, which are used everywhere. Each of these corresponds to a concept from category theory: for instance, what a Haskeller calls a "Functor" is what is categorically called an "endofunctor on Hask". Among users of the language who know any category theory at all, most have some familiarity with things at the level of what I've just said, but not much more. A knowledge of category theory at any higher level (like in the linked repo) is not at all common, statistically.
Also, not many of the common libraries are based on deep categorical ideas (lens  is an important exception) but even then, knowledge of the mathematics is useful if you want to dig into how the ideas are implemented, not if you're happy just using them. Learn as little or as much as you'd like.
CT is great for "looking to get really good at" FP. It writes out a parallel universe where certain things are easier and certain things are harder but the same core pillars of FP are intact. In this parallel universe there are myriad examples of constructions, techniques, and conceptual frameworks which can be "ported" back to FP. Likewise, some FP concepts have interesting "ported" versions in CT.
Learn CT when you want to build intuition for how to construct functional architecture. Don't learn it to start and don't even learn it when you run into Functor/Applicative/Monad. It's _not_ useful for understanding them in practical terms.
Go learn it when you start composing higher level constructions together comfortably and start running into questions about the most efficient ways to lay things out. It's _great_ for that.