`CompoundBytes` doesn't extend from `ByteString` and therefore couldn't be the result of `ByteString.++(ByteString)`. 

That's the main point: what is the distinction between `Bytes` and `ByteString` really? Either, there is a meaningful distinction (e.g. that ByteString gives stronger guarantees in terms of immutability), then if we want to preserve compatibility and provide a `ByteString.++` that returns a `ByteString` we need two kinds of ropes to preserve that distinction in types under composition, as well. Or, we don't care about the distinction between Bytes and ByteString, in which case we can rename ByteString to ImmutableHeapBytes (or similar) and remove ByteStrings in favor of the single CompoundBytes combinator.