Skip to content

Commit c2e751c

Browse files
authored
Merge pull request #117 from pjrt/master
Add `iscan` with its left, right, lazy and strict versions
2 parents 224eccb + 45ba11e commit c2e751c

File tree

4 files changed

+74
-1
lines changed

4 files changed

+74
-1
lines changed

Data/Vector.hs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,9 +143,11 @@ module Data.Vector (
143143
prescanl, prescanl',
144144
postscanl, postscanl',
145145
scanl, scanl', scanl1, scanl1',
146+
iscanl, iscanl',
146147
prescanr, prescanr',
147148
postscanr, postscanr',
148149
scanr, scanr', scanr1, scanr1',
150+
iscanr, iscanr',
149151

150152
-- * Conversions
151153

@@ -1456,6 +1458,16 @@ scanl' :: (a -> b -> a) -> a -> Vector b -> Vector a
14561458
{-# INLINE scanl' #-}
14571459
scanl' = G.scanl'
14581460

1461+
-- | /O(n)/ Scan over a vector with its index
1462+
iscanl :: (Int -> a -> b -> a) -> a -> Vector b -> Vector a
1463+
{-# INLINE iscanl #-}
1464+
iscanl = G.iscanl
1465+
1466+
-- | /O(n)/ Scan over a vector (strictly) with its index
1467+
iscanl' :: (Int -> a -> b -> a) -> a -> Vector b -> Vector a
1468+
{-# INLINE iscanl' #-}
1469+
iscanl' = G.iscanl'
1470+
14591471
-- | /O(n)/ Scan over a non-empty vector
14601472
--
14611473
-- > scanl f <x1,...,xn> = <y1,...,yn>
@@ -1506,6 +1518,16 @@ scanr' :: (a -> b -> b) -> b -> Vector a -> Vector b
15061518
{-# INLINE scanr' #-}
15071519
scanr' = G.scanr'
15081520

1521+
-- | /O(n)/ Right-to-left scan over a vector with its index
1522+
iscanr :: (Int -> a -> b -> b) -> b -> Vector a -> Vector b
1523+
{-# INLINE iscanr #-}
1524+
iscanr = G.iscanr
1525+
1526+
-- | /O(n)/ Right-to-left scan over a vector (strictly) with its index
1527+
iscanr' :: (Int -> a -> b -> b) -> b -> Vector a -> Vector b
1528+
{-# INLINE iscanr' #-}
1529+
iscanr' = G.iscanr'
1530+
15091531
-- | /O(n)/ Right-to-left scan over a non-empty vector
15101532
scanr1 :: (a -> a -> a) -> Vector a -> Vector a
15111533
{-# INLINE scanr1 #-}

Data/Vector/Generic.hs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,9 +126,11 @@ module Data.Vector.Generic (
126126
prescanl, prescanl',
127127
postscanl, postscanl',
128128
scanl, scanl', scanl1, scanl1',
129+
iscanl, iscanl',
129130
prescanr, prescanr',
130131
postscanr, postscanr',
131132
scanr, scanr', scanr1, scanr1',
133+
iscanr, iscanr',
132134

133135
-- * Conversions
134136

@@ -1721,6 +1723,23 @@ scanl' :: (Vector v a, Vector v b) => (a -> b -> a) -> a -> v b -> v a
17211723
{-# INLINE scanl' #-}
17221724
scanl' f z = unstream . Bundle.scanl' f z . stream
17231725

1726+
-- | /O(n)/ Scan over a vector with its index
1727+
iscanl :: (Vector v a, Vector v b) => (Int -> a -> b -> a) -> a -> v b -> v a
1728+
{-# INLINE iscanl #-}
1729+
iscanl f z =
1730+
unstream
1731+
. inplace (S.scanl (\a (i, b) -> f i a b) z . S.indexed) id
1732+
. stream
1733+
1734+
-- | /O(n)/ Scan over a vector (strictly) with its index
1735+
iscanl' :: (Vector v a, Vector v b) => (Int -> a -> b -> a) -> a -> v b -> v a
1736+
{-# INLINE iscanl' #-}
1737+
iscanl' f z =
1738+
unstream
1739+
. inplace (S.scanl' (\a (i, b) -> f i a b) z . S.indexed) id
1740+
. stream
1741+
1742+
17241743
-- | /O(n)/ Scan over a non-empty vector
17251744
--
17261745
-- > scanl f <x1,...,xn> = <y1,...,yn>
@@ -1771,6 +1790,22 @@ scanr' :: (Vector v a, Vector v b) => (a -> b -> b) -> b -> v a -> v b
17711790
{-# INLINE scanr' #-}
17721791
scanr' f z = unstreamR . Bundle.scanl' (flip f) z . streamR
17731792

1793+
-- | /O(n)/ Right-to-left scan over a vector with its index
1794+
iscanr :: (Vector v a, Vector v b) => (Int -> a -> b -> b) -> b -> v a -> v b
1795+
{-# INLINE iscanr #-}
1796+
iscanr f z =
1797+
unstreamR
1798+
. inplace (S.scanl (flip $ uncurry f) z . S.indexed) id
1799+
. streamR
1800+
1801+
-- | /O(n)/ Right-to-left scan over a vector (strictly) with its index
1802+
iscanr' :: (Vector v a, Vector v b) => (Int -> a -> b -> b) -> b -> v a -> v b
1803+
{-# INLINE iscanr' #-}
1804+
iscanr' f z =
1805+
unstreamR
1806+
. inplace (S.scanl' (flip $ uncurry f) z . S.indexed) id
1807+
. streamR
1808+
17741809
-- | /O(n)/ Right-to-left scan over a non-empty vector
17751810
scanr1 :: Vector v a => (a -> a -> a) -> v a -> v a
17761811
{-# INLINE scanr1 #-}

tests/Tests/Vector.hs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,10 +191,12 @@ testPolymorphicFunctions _ = $(testProperties [
191191
'prop_prescanl, 'prop_prescanl',
192192
'prop_postscanl, 'prop_postscanl',
193193
'prop_scanl, 'prop_scanl', 'prop_scanl1, 'prop_scanl1',
194+
'prop_iscanl, 'prop_iscanl',
194195

195196
'prop_prescanr, 'prop_prescanr',
196197
'prop_postscanr, 'prop_postscanr',
197-
'prop_scanr, 'prop_scanr', 'prop_scanr1, 'prop_scanr1'
198+
'prop_scanr, 'prop_scanr', 'prop_scanr1, 'prop_scanr1',
199+
'prop_iscanr, 'prop_iscanr'
198200
])
199201
where
200202
-- Prelude
@@ -357,6 +359,10 @@ testPolymorphicFunctions _ = $(testProperties [
357359
V.scanl1 `eq` scanl1
358360
prop_scanl1' :: P ((a -> a -> a) -> v a -> v a) = notNull2 ===>
359361
V.scanl1' `eq` scanl1
362+
prop_iscanl :: P ((Int -> a -> a -> a) -> a -> v a -> v a)
363+
= V.iscanl `eq` iscanl
364+
prop_iscanl' :: P ((Int -> a -> a -> a) -> a -> v a -> v a)
365+
= V.iscanl' `eq` iscanl
360366

361367
prop_prescanr :: P ((a -> a -> a) -> a -> v a -> v a)
362368
= V.prescanr `eq` prescanr
@@ -370,6 +376,10 @@ testPolymorphicFunctions _ = $(testProperties [
370376
= V.scanr `eq` scanr
371377
prop_scanr' :: P ((a -> a -> a) -> a -> v a -> v a)
372378
= V.scanr' `eq` scanr
379+
prop_iscanr :: P ((Int -> a -> a -> a) -> a -> v a -> v a)
380+
= V.iscanr `eq` iscanr
381+
prop_iscanr' :: P ((Int -> a -> a -> a) -> a -> v a -> v a)
382+
= V.iscanr' `eq` iscanr
373383
prop_scanr1 :: P ((a -> a -> a) -> v a -> v a) = notNull2 ===>
374384
V.scanr1 `eq` scanr1
375385
prop_scanr1' :: P ((a -> a -> a) -> v a -> v a) = notNull2 ===>

tests/Utilities.hs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,12 @@ indexedLeftFold fld f z = fld (uncurry . f) z . zip [0..]
297297
ifoldl :: (a -> Int -> a -> a) -> a -> [a] -> a
298298
ifoldl = indexedLeftFold foldl
299299

300+
iscanl :: (Int -> a -> b -> a) -> a -> [b] -> [a]
301+
iscanl f z = scanl (\a (i, b) -> f i a b) z . zip [0..]
302+
303+
iscanr :: (Int -> a -> b -> b) -> b -> [a] -> [b]
304+
iscanr f z = scanr (uncurry f) z . zip [0..]
305+
300306
ifoldr :: (Int -> a -> b -> b) -> b -> [a] -> b
301307
ifoldr f z = foldr (uncurry f) z . zip [0..]
302308

0 commit comments

Comments
 (0)