Skip to content

Commit 9b07e9f

Browse files
authored
Merge pull request #98 from haskell-works/new-unzipFromListN2-function
New unzipFromListN2 function
2 parents 42262bf + d2e454a commit 9b07e9f

File tree

2 files changed

+40
-5
lines changed

2 files changed

+40
-5
lines changed

src/HaskellWorks/Data/Vector/Storable.hs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ module HaskellWorks.Data.Vector.Storable
1010
, constructSI
1111
, construct2N
1212
, construct64UnzipN
13+
, unzipFromListN2
1314
) where
1415

1516
import Control.Monad.ST (ST, runST)
@@ -18,7 +19,7 @@ import Data.Vector.Storable (Storable)
1819
import Data.Word
1920
import Foreign.ForeignPtr
2021
import HaskellWorks.Data.Vector.AsVector8
21-
import Prelude hiding (foldMap)
22+
import Prelude hiding (abs, foldMap)
2223

2324
import qualified Data.ByteString as BS
2425
import qualified Data.Vector.Generic as DVG
@@ -126,3 +127,25 @@ construct64UnzipN nBytes xs = (DVS.unsafeCast ibv, DVS.unsafeCast bpv)
126127
DVSM.set (DVSM.take ibl ibmv) 0
127128
DVSM.set (DVSM.take bpl bpmv) 0
128129
return (DVSM.length (DVSM.drop ibl ibmv), DVSM.length (DVSM.drop bpl bpmv))
130+
131+
unzipFromListN2 :: (Storable a, Storable b) => Int -> [(a, b)] -> (DVS.Vector a, DVS.Vector b)
132+
unzipFromListN2 n abs = runST $ do
133+
mas <- DVSM.unsafeNew n
134+
mbs <- DVSM.unsafeNew n
135+
len <- go 0 mas mbs abs
136+
as <- DVG.unsafeFreeze (DVSM.take len mas)
137+
bs <- DVG.unsafeFreeze (DVSM.take len mbs)
138+
return (as, bs)
139+
where go :: (Storable c, Storable d)
140+
=> Int
141+
-> DVSM.MVector s c
142+
-> DVSM.MVector s d
143+
-> [(c, d)]
144+
-> ST s Int
145+
go i _ _ [] = return i
146+
go i mvc mvd ((c, d):cds) = if i < n
147+
then do
148+
DVSM.write mvc i c
149+
DVSM.write mvd i d
150+
go (i + 1) mvc mvd cds
151+
else return i

test/HaskellWorks/Data/Vector/StorableSpec.hs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ module HaskellWorks.Data.Vector.StorableSpec
66
( spec
77
) where
88

9-
import Control.Monad.ST (ST)
10-
import Data.Vector.Storable (Storable)
11-
import HaskellWorks.Data.Vector.Storable (construct64UnzipN)
9+
import Control.Monad.ST (ST)
10+
import Data.Vector.Storable (Storable)
1211
import HaskellWorks.Hspec.Hedgehog
1312
import Hedgehog
13+
import Prelude hiding (abs)
1414
import Test.Hspec
1515

1616
import qualified Data.ByteString as BS
@@ -51,11 +51,23 @@ spec = describe "HaskellWorks.Data.Vector.StorableSpec" $ do
5151
al <- forAll $ pure $ BS.length (mconcat ass)
5252
bl <- forAll $ pure $ BS.length (mconcat bss)
5353
len <- forAll $ pure $ al + bl
54-
let res = construct64UnzipN len (zip ass bss)
54+
let res = DVS.construct64UnzipN len (zip ass bss)
5555
let ra = BS.toByteString (fst res)
5656
let rb = BS.toByteString (snd res)
5757
ra === BS.padded ((BS.length as + 7) `div` 8 * 8) as
5858
rb === BS.padded ((BS.length bs + 7) `div` 8 * 8) bs
59+
it "unzipFromListN2" $ requireProperty $ do
60+
abs <- forAll $ G.list (R.linear 0 8) $ (,)
61+
<$> G.word8 R.constantBounded
62+
<*> G.word8 R.constantBounded
63+
len <- forAll $ G.int (R.linear 0 8)
64+
as <- forAll $ pure $ fmap fst abs
65+
bs <- forAll $ pure $ fmap snd abs
66+
(va, vb) <- forAll $ pure $ DVS.unzipFromListN2 len abs
67+
let eva = DVS.fromList (take len as)
68+
let evb = DVS.fromList (take len bs)
69+
va === eva
70+
vb === evb
5971

6072
dupList :: [a] -> [a]
6173
dupList (a:as) = (a:a:dupList as)

0 commit comments

Comments
 (0)