I agree with you. Varnish is made for being a website cache that's a real part of the application. It needs to be extremely flexible and programmable. HAProxy needs less flexibility on the caching stuff but more on the conditions to switch a server on/off, regulate traffic or deal with DDoS. Nowadays we see a lot of combinations of the two, initially to get SSL offloading at the haproxy layer, but also for cache deduplication: when you configure haproxy to perform load-bounded consistent hashing to your varnish caches, you get a very efficient cache layer that avoids duplication unless the load starts to grow for some objects in which case these objects will be fetched from adjacent caches. That delivers the best power: unified storage with replication of highly loaded objects only. The cache in haproxy was initially called the "favicon cache" because we don't want it to become a complex cache. And we've succeeded at this, nobody ever manages nor flushes that cache. It's strict and in case of doubt it will refrain from caching. You can use it to avoid passing certain tiny requests to varnish when the cost of passing them over the network outweights their benefit (e.g. favicon or tiny gif bullets that compose pages). But varnish definitely is the de-facto standard cache. The 3 components you name are so commonly found together that some people tend to confuse them (due to the small overlap), but they all excel in their respective areas.
My point was mainly that Varnish can often serve as a complete replacement for HAProxy, rather than a complement to it. No doubt there are features/things in HAProxy that are not easily expressed in Varnish (although in principle you can do pretty much anything in Varnish since you can extend it), but for many common use cases Varnish will work as a fine load balancer, eliminating the need for HAProxy altogether. The only additional thing you need is something like Hitch or Pound to do TLS.
OK I see. Yes for some use cases that's possible. But that seriously limits your load balancing capabilities. And having to deploy Hitch or Pound for TLS still requires an extra component that's not designed to deal with traffic spikes, denial or services etc that are often met in environments where you deploy caches.