Eq and Ord instances
[darcs-mirrors/vector.git] / Data / Vector / IVector.hs
index 89b4e7a..e3e0370 100644 (file)
@@ -29,9 +29,15 @@ module Data.Vector.IVector (
   -- * Subvectors
   slice, extract, takeSlice, take, dropSlice, drop,
 
+  -- * Permutations
+  (//),
+
   -- * Mapping and zipping
   map, zipWith,
 
+  -- * Comparisons
+  eq, cmp,
+
   -- * Filtering
   filter, takeWhileSlice, takeWhile, dropWhileSlice, dropWhile,
 
@@ -60,6 +66,9 @@ module Data.Vector.IVector (
 import qualified Data.Vector.MVector as MVector
 import           Data.Vector.MVector ( MVector )
 
+import qualified Data.Vector.MVector.Mut as Mut
+import           Data.Vector.MVector.Mut ( Mut )
+
 import qualified Data.Vector.Stream as Stream
 import           Data.Vector.Stream ( Stream )
 import           Data.Vector.Stream.Size
@@ -112,9 +121,9 @@ class IVector v a where
 -- ------
 
 -- | Construct a pure vector from a monadic initialiser 
-new :: IVector v a => (forall mv m. MVector mv m a => m (mv a)) -> v a
+new :: IVector v a => Mut a -> v a
 {-# INLINE_STREAM new #-}
-new init = vnew init
+new m = vnew (Mut.run m)
 
 -- | Convert a vector to a 'Stream'
 stream :: IVector v a => v a -> Stream a
@@ -129,13 +138,16 @@ stream v = v `seq` (Stream.unfold get 0 `Stream.sized` Exact n)
 
 -- | Create a vector from a 'Stream'
 unstream :: IVector v a => Stream a -> v a
-{-# INLINE_STREAM unstream #-}
-unstream s = new (MVector.unstream s)
+{-# INLINE unstream #-}
+unstream s = new (Mut.unstream s)
 
 {-# RULES
 
 "stream/unstream [IVector]" forall s.
-  stream (unstream s) = s
+  stream (new (Mut.unstream s)) = s
+
+"Mut.unstream/stream/new [IVector]" forall p.
+  Mut.unstream (stream (new p)) = p
 
  #-}
 
@@ -149,7 +161,7 @@ length v = vlength v
 {-# RULES
 
 "length/unstream [IVector]" forall s.
-  length (unstream s) = Stream.length s
+  length (new (Mut.unstream s)) = Stream.length s
 
   #-}
 
@@ -209,13 +221,13 @@ last v = v ! (length v - 1)
 {-# RULES
 
 "(!)/unstream [IVector]" forall i s.
-  unstream s ! i = s Stream.!! i
+  new (Mut.unstream s) ! i = s Stream.!! i
 
 "head/unstream [IVector]" forall s.
-  head (unstream s) = Stream.head s
+  head (new (Mut.unstream s)) = Stream.head s
 
 "last/unstream [IVector]" forall s.
-  last (unstream s) = Stream.last s
+  last (new (Mut.unstream s)) = Stream.last s
 
  #-}
 
@@ -261,16 +273,24 @@ drop n = unstream . Stream.drop n . stream
 {-# RULES
 
 "slice/extract [IVector]" forall i n s.
-  slice (unstream s) i n = extract (unstream s) i n
+  slice (new (Mut.unstream s)) i n = extract (new (Mut.unstream s)) i n
 
 "takeSlice/unstream [IVector]" forall n s.
-  takeSlice n (unstream s) = take n (unstream s)
+  takeSlice n (new (Mut.unstream s)) = take n (new (Mut.unstream s))
 
 "dropSlice/unstream [IVector]" forall n s.
-  dropSlice n (unstream s) = drop n (unstream s)
+  dropSlice n (new (Mut.unstream s)) = drop n (new (Mut.unstream s))
 
   #-}
 
+-- Permutations
+-- ------------
+
+(//) :: IVector v a => v a -> [(Int, a)] -> v a
+{-# INLINE (//) #-}
+v // us = new (Mut.update (Mut.unstream (stream v))
+                          (Stream.fromList us))
+
 -- Mapping/zipping
 -- ---------------
 
@@ -279,11 +299,29 @@ map :: (IVector v a, IVector v b) => (a -> b) -> v a -> v b
 {-# INLINE map #-}
 map f = unstream . Stream.map f . stream
 
+{-# RULES
+
+"in-place map [IVector]" forall f m.
+  Mut.unstream (Stream.map f (stream (new m))) = Mut.map f m
+
+  #-}
+
 -- | Zip two vectors with the given function.
 zipWith :: (IVector v a, IVector v b, IVector v c) => (a -> b -> c) -> v a -> v b -> v c
 {-# INLINE zipWith #-}
 zipWith f xs ys = unstream (Stream.zipWith f (stream xs) (stream ys))
 
+-- Comparisons
+-- -----------
+
+eq :: (IVector v a, Eq a) => v a -> v a -> Bool
+{-# INLINE eq #-}
+xs `eq` ys = stream xs == stream ys
+
+cmp :: (IVector v a, Ord a) => v a -> v a -> Ordering
+{-# INLINE cmp #-}
+cmp xs ys = compare (stream xs) (stream ys)
+
 -- Filtering
 -- ---------
 
@@ -323,10 +361,10 @@ dropWhile f = unstream . Stream.dropWhile f . stream
 {-# RULES
 
 "takeWhileSlice/unstream" forall f s.
-  takeWhileSlice f (unstream s) = takeWhile f (unstream s)
+  takeWhileSlice f (new (Mut.unstream s)) = takeWhile f (new (Mut.unstream s))
 
 "dropWhileSlice/unstream" forall f s.
-  dropWhileSlice f (unstream s) = dropWhile f (unstream s)
+  dropWhileSlice f (new (Mut.unstream s)) = dropWhile f (new (Mut.unstream s))
 
  #-}