We do expose CAS for boxed data, and we depend on that for various concurrent data structures (e.g. Michael-scott queues).
But it's a messy business:
<explanation> You have to fight hard against the GHC optimizer to prevent it from performing optimizations (e.g. unbox and rebox an Int) that completely destroy pointer equality (in all runs of the program). The way that we've codified our solution to this is to use abstract "Ticket"s (based on the Any kind) that GHC is not supposed to be able to see through. These are used to abstractly represent old reads when you come back to do a new CAS operation:
Even then, there was a bunch of careful NOINLINE's and other business necessary to achieve something workable, and it's highly GHC specific. If we were to expose CAS on boxed "Data.Vector", I think it would only make sense as the ticketed interface above (raw CAS is useless, and will just condemn others to the same problems we had).
</explanation>
As a result of all this the CAS for Data.Vector would have a different signature (unless we wanted to force Storable/Unbox to use Tickets), and thus couldn't go in the "MVector" type class along with all the other basic operations that are uniform across representations.
That said, it's easy to provide CAS from a separate "vector-atomics" package, because Data.Vector exposes the MVector constructor that lets you get at the underlying MutableArray. So we certainly can provide the functionality somewhere, somehow.
-Ryan