[commit: packages/containers] master: Improve *> (c2b2048)
git at git.haskell.org
git at git.haskell.org
Fri Dec 18 22:12:12 UTC 2015
Repository : ssh://git@git.haskell.org/containers
On branch : master
Link : http://git.haskell.org/packages/containers.git/commitdiff/c2b20485f22202dc7227ef00ae28d706c8df8d4d
>---------------------------------------------------------------
commit c2b20485f22202dc7227ef00ae28d706c8df8d4d
Author: David Feuer <David.Feuer at gmail.com>
Date: Tue Mar 10 19:57:49 2015 -0400
Improve *>
Use `applicativeTree` and techniques from `<*>` to make `*>`
share as much as possible and offer immediate access with correct
time bounds.
>---------------------------------------------------------------
c2b20485f22202dc7227ef00ae28d706c8df8d4d
Data/Sequence.hs | 89 +++++++++++++++++++++++++++++++++++++++++++++++---------
1 file changed, 75 insertions(+), 14 deletions(-)
diff --git a/Data/Sequence.hs b/Data/Sequence.hs
index 9de2228..91c62d8 100644
--- a/Data/Sequence.hs
+++ b/Data/Sequence.hs
@@ -271,13 +271,13 @@ instance Monad Seq where
instance Applicative Seq where
pure = singleton
- xs *> ys = replicateSeq (length xs) ys
+ xs *> ys = cycleN (length xs) ys
- fs <*> xs = case viewl fs of
+ fs <*> xs@(Seq xsFT) = case viewl fs of
EmptyL -> empty
firstf :< fs' -> case viewr fs' of
EmptyR -> fmap firstf xs
- Seq fs''FT :> lastf -> case (rigidify . (\(Seq a) -> a)) xs of
+ Seq fs''FT :> lastf -> case rigidify xsFT of
RigidEmpty -> empty
RigidOne (Elem x) -> fmap ($x) fs
RigidTwo (Elem x1) (Elem x2) ->
@@ -933,18 +933,79 @@ replicateM n x
| n >= 0 = unwrapMonad (replicateA n (WrapMonad x))
| otherwise = error "replicateM takes a nonnegative integer argument"
--- | @'replicateSeq' n xs@ concatenates @n@ copies of @xs at .
-replicateSeq :: Int -> Seq a -> Seq a
-replicateSeq n s
- | n < 0 = error "replicateSeq takes a nonnegative integer argument"
+-- | @'cycleN' n xs@ concatenates @n@ copies of @xs at .
+cycleN :: Int -> Seq a -> Seq a
+cycleN n xs
+ | n < 0 = error "cycleN takes a nonnegative integer argument"
| n == 0 = empty
- | otherwise = go n s
- where
- -- Invariant: k >= 1
- go 1 xs = xs
- go k xs | even k = kxs
- | otherwise = xs >< kxs
- where kxs = go (k `quot` 2) $! (xs >< xs)
+ | n == 1 = xs
+cycleN n (Seq xsFT) = case rigidify xsFT of
+ RigidEmpty -> empty
+ RigidOne (Elem x) -> replicate n x
+ RigidTwo x1 x2 -> Seq $
+ Deep (n*2) pair
+ (runIdentity $ applicativeTree (n-2) 2 (Identity (node2 x1 x2)))
+ pair
+ where pair = Two x1 x2
+ RigidThree x1 x2 x3 -> Seq $
+ Deep (n*3) triple
+ (runIdentity $ applicativeTree (n-2) 3 (Identity (node3 x1 x2 x3)))
+ triple
+ where triple = Three x1 x2 x3
+ RigidFull r@(Rigid s pr _m sf) -> Seq $
+ Deep (n*s)
+ (nodeToDigit pr)
+ (cycleNMiddle (n-2) r)
+ (nodeToDigit sf)
+
+cycleNMiddle
+ :: Sized c => Int
+ -> Rigid c
+ -> FingerTree (Node c)
+
+STRICT_1_OF_2(cycleNMiddle)
+
+-- Not at the bottom yet
+
+cycleNMiddle n
+ (Rigid s pr (DeepTh sm prm mm sfm) sf)
+ = Deep (sm + s * (n + 1)) -- note: sm = s - size pr - size sf
+ (digit12ToDigit prm)
+ (cycleNMiddle n
+ (Rigid s (squashL pr prm) mm (squashR sfm sf)))
+ (digit12ToDigit sfm)
+
+-- At the bottom
+
+cycleNMiddle n
+ (Rigid s pr EmptyTh sf)
+ = deep
+ (One sf)
+ (runIdentity $ applicativeTree n s (Identity converted))
+ (One pr)
+ where converted = node2 pr sf
+
+cycleNMiddle n
+ (Rigid s pr (SingleTh q) sf)
+ = deep
+ (Two q sf)
+ (runIdentity $ applicativeTree n s (Identity converted))
+ (Two pr q)
+ where converted = node3 pr q sf
+
+{-# SPECIALIZE
+ cycleNMiddle
+ :: Int
+ -> Rigid (Node c)
+ -> FingerTree (Node (Node c))
+ #-}
+{-# SPECIALIZE
+ cycleNMiddle
+ :: Int
+ -> Rigid (Elem c)
+ -> FingerTree (Node (Elem c))
+ #-}
+
-- | /O(1)/. Add an element to the left end of a sequence.
-- Mnemonic: a triangle with the single element at the pointy end.
More information about the ghc-commits
mailing list