For tuples move is implemented as pairwise move each underlying array. However it's possible for arrays corresponding to different to alias thus breaking move implementation. As an example:
Reference impl
"src = [(0,100),(1,101),(2,102),(3,103)]"
"dst = [(100,0),(101,1),(102,2),(103,3)]"
"dst = [(0,100),(1,101),(2,102),(3,103)]"
move
"src = [(0,100),(1,101),(2,102),(3,103)]"
"dst = [(100,0),(101,1),(102,2),(103,3)]"
"dst = [(0,0),(1,1),(2,2),(3,3)]"
Which is obviously breaks specification. However I don't see any easy fix. We'll need to check all underlying arrays for overlap and we don't have machinery for that
It turn out
moveis not implemented correctly for unboxed vector which use structure of arrays (SoA) representation. Here ismove's specification:For tuples move is implemented as pairwise move each underlying array. However it's possible for arrays corresponding to different to alias thus breaking
moveimplementation. As an example:{-# LANGUAGE ImportQualifiedPost #-} {-# LANGUAGE TypeFamilies #-} moduleMVwhereimportControl.Monad.PrimitiveimportData.Vector.UnboxedqualifiedasVUimportData.Vector.Unboxed.MutablequalifiedasMVUimportData.Vector.Generic.MutablequalifiedasMVG-- Reference implementation for move:moveSpec:: (MVG.MVectorva, PrimMonadm, PrimStatem~s) =>vsa->vsa->m() moveSpec tgt src =do tmp <-MVG.clone src MVG.copy tgt tmp problemSoA::IO() problemSoA =doputStrLn"Reference impl" testMove moveSpec putStrLn"\nmove" testMove MVU.move where testMove fun =do va <-MVU.generate 4id vb <-MVU.generate 4 (+100) let src =MVU.zip va vb dst =MVU.zip vb va print. ("src = "++) .show=<<VU.freeze src print. ("dst = "++) .show=<<VU.freeze dst fun dst src print. ("dst = "++) .show=<<VU.freeze dstproduces
Which is obviously breaks specification. However I don't see any easy fix. We'll need to check all underlying arrays for overlap and we don't have machinery for that