I don't think coming across these problems in general is Haskell specific. We've grown enough to bubble these issues up in this Haskell project, but would have needed to do something much sooner if this was C++.
> make you more comfortable with this stuff
Which stuff are you referring to?
Overall I'd love if all builds were significantly faster, so we contribute to upstream GHC to make it better in the ways we come across. Our platform has a deployment SLA that we strive to maintain as our "target build time".
I should have emphasized the speed of deployment being a first order concern more. We certainly can (and do) build our code for every change, but not at the speed that we want to be updating.
We use a monorepo for all of the benefits it has, and deploying fast business logic updates this way helps mitigate one of its downsides (particularly when you've maximally parallelized the build). I've found https://danluu.com/monorepo/ to give a quick overview of how chopping up the repo would have separate downsides.
The section about "Sticky Shared Objects" speaks directly to mutable state across code modifications, just with a Haskell-minded focus.
I'm assuming you're asking what's important in writing "production" Haskell rather than "toy example" Haskell.
Ixiaus's point about mechanics more than theory certainly rings true, though we did think a lot about whether to use GADTs for the Dimension type.
Overall I see this as similar to writing "production" code in other languages, going through a couple feedback loops using real use-cases. Profiling to find the bottlenecks, observing how APIs are used in practice compared to intent, and reaching the service to a stable equilibrium.
Build times for this library haven't cropped up as a first-order concern. Using GHCI and `stack test` for the dev workflow has been fast enough (though could always be better).
One of the cases we found while performance profiling was a tradeoff between memory usage and computation completion. On certain requests FXL would use too much memory and be halted by the equivalent to AllocationLimits, while Haxl would happily plow on using less memory and complete the request. When looking at many of those requests in aggregate, the end result would have more successfully completed requests but with longer response times mixed in. Completing more requests was seen as a win over the apparent decrease in throughput.
Query sharding is at the data source layer, which Haxl doesn't delve into. It's up to each data source integration with Haxl to do the appropriate routing/etc.
Interpreted code was no longer cutting it for perf reasons, and any time you create your own language you end up reinventing the entire tool chain (debuggers, profilers, etc.). Haskell provides so much functionality in the language itself and has mature solutions to the other issues plaguing us in FXL, so it was a natural choice.
> make you more comfortable with this stuff
Which stuff are you referring to? Overall I'd love if all builds were significantly faster, so we contribute to upstream GHC to make it better in the ways we come across. Our platform has a deployment SLA that we strive to maintain as our "target build time".