Add clone and change fusion rules accordingly
authorRoman Leshchinskiy <rl@cse.unsw.edu.au>
Sat, 17 Apr 2010 07:16:04 +0000 (07:16 +0000)
committerRoman Leshchinskiy <rl@cse.unsw.edu.au>
Sat, 17 Apr 2010 07:16:04 +0000 (07:16 +0000)
Data/Vector/Generic.hs
Data/Vector/Generic/New.hs

index 2339da2..50e9e7e 100644 (file)
@@ -137,6 +137,14 @@ new :: Vector v a => New v a -> v a
 {-# INLINE_STREAM new #-}
 new m = m `seq` runST (unsafeFreeze =<< New.run m)
 
+clone :: Vector v a => v a -> New v a
+{-# INLINE_STREAM clone #-}
+clone v = v `seq` New.create (
+  do
+    mv <- M.new (length v)
+    unsafeCopy mv v
+    return mv)
+
 -- | Convert a vector to a 'Stream'
 stream :: Vector v a => v a -> Stream a
 {-# INLINE_STREAM stream #-}
@@ -160,8 +168,11 @@ unstream s = new (New.unstream s)
 "stream/unstream [Vector]" forall s.
   stream (new (New.unstream s)) = s
 
-"New.unstream/stream/new [Vector]" forall p.
-  New.unstream (stream (new p)) = p
+"New.unstream/stream [Vector]" forall v.
+  New.unstream (stream v) = clone v
+
+"clone/new [Vector]" forall p.
+  clone (new p) = p
 
  #-}
 
@@ -329,7 +340,7 @@ v ++ w = unstream (stream v Stream.++ stream w)
 -- | Create a copy of a vector. Useful when dealing with slices.
 force :: Vector v a => v a -> v a
 {-# INLINE_STREAM force #-}
-force = unstream . stream
+force v = new (clone v)
 
 {-# RULES
 
@@ -538,7 +549,7 @@ unsafeDrop n v = unsafeSlice n (length v - n) v
 unsafeAccum_stream
   :: Vector v a => (a -> b -> a) -> v a -> Stream (Int,b) -> v a
 {-# INLINE unsafeAccum_stream #-}
-unsafeAccum_stream f v s = new (New.accum f (New.unstream (stream v)) s)
+unsafeAccum_stream f v s = new (New.accum f (clone v) s)
 
 unsafeAccum :: Vector v a => (a -> b -> a) -> v a -> [(Int,b)] -> v a
 {-# INLINE unsafeAccum #-}
@@ -557,7 +568,7 @@ unsafeAccumulate_ f v is xs
 
 accum_stream :: Vector v a => (a -> b -> a) -> v a -> Stream (Int,b) -> v a
 {-# INLINE accum_stream #-}
-accum_stream f v s = new (New.accum f (New.unstream (stream v)) s)
+accum_stream f v s = new (New.accum f (clone v) s)
 
 accum :: Vector v a => (a -> b -> a) -> v a -> [(Int,b)] -> v a
 {-# INLINE accum #-}
@@ -577,7 +588,7 @@ accumulate_ f v is xs = accum_stream f v (Stream.zipWith (,) (stream is)
 
 unsafeUpdate_stream :: Vector v a => v a -> Stream (Int,a) -> v a
 {-# INLINE unsafeUpdate_stream #-}
-unsafeUpdate_stream v s = new (New.unsafeUpdate (New.unstream (stream v)) s)
+unsafeUpdate_stream v s = new (New.unsafeUpdate (clone v) s)
 
 unsafeUpd :: Vector v a => v a -> [(Int, a)] -> v a
 {-# INLINE unsafeUpd #-}
@@ -594,7 +605,7 @@ unsafeUpdate_ v is w
 
 update_stream :: Vector v a => v a -> Stream (Int,a) -> v a
 {-# INLINE update_stream #-}
-update_stream v s = new (New.update (New.unstream (stream v)) s)
+update_stream v s = new (New.update (clone v) s)
 
 (//) :: Vector v a => v a -> [(Int, a)] -> v a
 {-# INLINE (//) #-}
index 400b913..dfabef5 100644 (file)
@@ -13,7 +13,8 @@
 --
 
 module Data.Vector.Generic.New (
-  New(..), run, apply, modify, unstream, transform, unstreamR, transformR,
+  New(..), create, run, apply, modify,
+  unstream, transform, unstreamR, transformR,
   accum, update, reverse,
   slice, init, tail, take, drop,
   unsafeSlice, unsafeInit, unsafeTail,
@@ -36,6 +37,10 @@ import Prelude hiding ( init, tail, take, drop, reverse, map, filter )
 
 data New v a = New (forall s. ST s (Mutable v s a))
 
+create :: (forall s. ST s (Mutable v s a)) -> New v a
+{-# INLINE create #-}
+create = New
+
 run :: New v a -> ST s (Mutable v s a)
 {-# INLINE run #-}
 run (New p) = p