Skip to content

Commit 22ef7de

Browse files
committed
Optimize *> and >> for Seq
Based on a discussion with Ross Paterson, use a multiplication- by-doubling algorithm to improve asymptotic time and space performance.
1 parent e083f68 commit 22ef7de

File tree

1 file changed

+15
-0
lines changed

1 file changed

+15
-0
lines changed

Data/Sequence.hs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,11 +228,13 @@ instance Monad Seq where
228228
return = singleton
229229
xs >>= f = foldl' add empty xs
230230
where add ys x = ys >< f x
231+
(>>) = (*>)
231232

232233
instance Applicative Seq where
233234
pure = singleton
234235
fs <*> xs = foldl' add empty fs
235236
where add ys f = ys >< fmap f xs
237+
xs *> ys = replicateSeq (length xs) ys
236238

237239
instance MonadPlus Seq where
238240
mzero = empty
@@ -655,6 +657,19 @@ replicateM n x
655657
| n >= 0 = unwrapMonad (replicateA n (WrapMonad x))
656658
| otherwise = error "replicateM takes a nonnegative integer argument"
657659

660+
-- | @'replicateSeq' n xs@ concatenates @n@ copies of @xs@.
661+
replicateSeq :: Int -> Seq a -> Seq a
662+
replicateSeq n xs
663+
| n < 0 = error "replicateSeq takes a nonnegative integer argument"
664+
| n == 0 = empty
665+
| otherwise = go n xs
666+
where
667+
-- Invariant: k >= 1
668+
go 1 xs = xs
669+
go k xs | even k = kxs
670+
| otherwise = xs >< kxs
671+
where kxs = go (k `quot` 2) $! (xs >< xs)
672+
658673
-- | /O(1)/. Add an element to the left end of a sequence.
659674
-- Mnemonic: a triangle with the single element at the pointy end.
660675
(<|) :: a -> Seq a -> Seq a

0 commit comments

Comments
 (0)