1
+ {- OPTIONS_GHC -ddump-simpl #-}
1
2
{-# LANGUAGE CPP #-}
2
3
#include "containers.h"
3
4
{-# LANGUAGE BangPatterns #-}
7
8
{-# LANGUAGE DeriveLift #-}
8
9
{-# LANGUAGE StandaloneDeriving #-}
9
10
{-# LANGUAGE FlexibleInstances #-}
11
+ {-# LANGUAGE GADTs #-}
10
12
{-# LANGUAGE InstanceSigs #-}
11
13
{-# LANGUAGE ScopedTypeVariables #-}
12
14
{-# LANGUAGE TemplateHaskellQuotes #-}
@@ -193,6 +195,7 @@ module Data.Sequence.Internal (
193
195
node2 ,
194
196
node3 ,
195
197
#endif
198
+ bongo
196
199
) where
197
200
198
201
import Utils.Containers.Internal.Prelude hiding (
@@ -210,7 +213,7 @@ import Control.Applicative ((<$>), (<**>), Alternative,
210
213
import qualified Control.Applicative as Applicative
211
214
import Control.DeepSeq (NFData (rnf ))
212
215
import Control.Monad (MonadPlus (.. ))
213
- import Data.Monoid (Monoid (.. ))
216
+ import Data.Monoid (Monoid (.. ), Endo ( .. ), Dual ( .. ) )
214
217
import Data.Functor (Functor (.. ))
215
218
import Utils.Containers.Internal.State (State (.. ), execState )
216
219
import Data.Foldable (foldr' , toList )
@@ -250,6 +253,7 @@ import Data.Functor.Identity (Identity(..))
250
253
import Utils.Containers.Internal.StrictPair (StrictPair (.. ), toPair )
251
254
import Control.Monad.Zip (MonadZip (.. ))
252
255
import Control.Monad.Fix (MonadFix (.. ), fix )
256
+ import Data.Sequence.Internal.Depth (Depth_ (.. ), Depth2_ (.. ))
253
257
254
258
default ()
255
259
@@ -394,16 +398,38 @@ fmapSeq f (Seq xs) = Seq (fmap (fmap f) xs)
394
398
#-}
395
399
#endif
396
400
401
+ -- type Depth = Depth_ Elem Node
402
+ type Depth = Depth_ Node
403
+ type Depth2 = Depth2_ Node
404
+
397
405
instance Foldable Seq where
398
406
#ifdef __GLASGOW_HASKELL__
399
407
foldMap :: forall m a . Monoid m => (a -> m ) -> Seq a -> m
400
- foldMap = coerce (foldMap :: (Elem a -> m ) -> FingerTree (Elem a ) -> m )
408
+ foldMap f (Seq t0) = foldMapFT Bottom t0
409
+ where
410
+ foldMapBlob :: Depth (Elem a ) t -> t -> m
411
+ foldMapBlob Bottom (Elem a) = f a
412
+ foldMapBlob (Deeper w) (Node2 _ x y) = foldMapBlob w x <> foldMapBlob w y
413
+ foldMapBlob (Deeper w) (Node3 _ x y z) = foldMapBlob w x <> foldMapBlob w y <> foldMapBlob w z
414
+
415
+ foldMapFT :: Depth (Elem a ) t -> FingerTree t -> m
416
+ foldMapFT ! _ EmptyT = mempty
417
+ foldMapFT w (Single t) = foldMapBlob w t
418
+ foldMapFT w (Deep _ pr m sf) =
419
+ foldMap (foldMapBlob w) pr
420
+ <> foldMapFT (Deeper w) m
421
+ <> foldMap (foldMapBlob w) sf
401
422
402
423
foldr :: forall a b . (a -> b -> b ) -> b -> Seq a -> b
403
- foldr = coerce (foldr :: (Elem a -> b -> b ) -> b -> FingerTree (Elem a ) -> b )
424
+ -- We define this explicitly so we can inline the foldMap. And we don't
425
+ -- define it as a coercion of the FingerTree version because we want users
426
+ -- to have the option of (effectively) inlining it explicitly.
427
+ foldr f z t = appEndo (GHC.Exts. inline foldMap (coerce f) t) z
404
428
405
429
foldl :: forall b a . (b -> a -> b ) -> b -> Seq a -> b
406
- foldl = coerce (foldl :: (b -> Elem a -> b ) -> b -> FingerTree (Elem a ) -> b )
430
+ -- Should we define this by hand to associate optimally? Or is GHC
431
+ -- clever enough to do that for us?
432
+ foldl f z t = appEndo (getDual (GHC.Exts. inline foldMap (Dual . Endo . flip f) t)) z
407
433
408
434
foldr' :: forall a b . (a -> b -> b ) -> b -> Seq a -> b
409
435
foldr' = coerce (foldr' :: (Elem a -> b -> b ) -> b -> FingerTree (Elem a ) -> b )
@@ -442,7 +468,37 @@ instance Foldable Seq where
442
468
instance Traversable Seq where
443
469
#if __GLASGOW_HASKELL__
444
470
{-# INLINABLE traverse #-}
445
- #endif
471
+ traverse :: forall f a b . Applicative f => (a -> f b ) -> Seq a -> f (Seq b )
472
+ traverse f (Seq t0) = Seq <$> traverseFT Bottom2 t0
473
+ where
474
+ traverseFT :: Depth2 (Elem a ) t (Elem b ) u -> FingerTree t -> f (FingerTree u )
475
+ traverseFT ! _ EmptyT = pure EmptyT
476
+ traverseFT w (Single t) = Single <$> traverseBlob w t
477
+ traverseFT w (Deep s pr m sf) = liftA3 (Deep s)
478
+ (traverse (traverseBlob w) pr)
479
+ (traverseFT (Deeper2 w) m)
480
+ (traverse (traverseBlob w) sf)
481
+
482
+ -- Traverse a 2-3 tree, given its height.
483
+ traverseBlob :: Depth2 (Elem a ) t (Elem b ) u -> t -> f u
484
+ traverseBlob Bottom2 (Elem a) = Elem <$> f a
485
+
486
+ -- We have a special case here to avoid needing to `fmap Elem` over
487
+ -- each of the leaves, in case that's not free in the relevant functor.
488
+ -- We still end up using extra fmaps for the very first level of the
489
+ -- FingerTree and the Seq constructor. While we *could* avoid that,
490
+ -- doing so requires a good bit of extra code to save *at most* nine
491
+ -- fmap applications for the sequence. It would also save on Depth
492
+ -- comparisons, but I doubt that matters very much.
493
+ traverseBlob (Deeper2 Bottom2 ) (Node2 s (Elem x) (Elem y))
494
+ = liftA2 (\ x' y' -> Node2 s (Elem x') (Elem y')) (f x) (f y)
495
+ traverseBlob (Deeper2 Bottom2 ) (Node3 s (Elem x) (Elem y) (Elem z))
496
+ = liftA3 (\ x' y' z' -> Node3 s (Elem x') (Elem y') (Elem z'))
497
+ (f x) (f y) (f z)
498
+
499
+ traverseBlob (Deeper2 w) (Node2 s x y) = liftA2 (Node2 s) (traverseBlob w x) (traverseBlob w y)
500
+ traverseBlob (Deeper2 w) (Node3 s x y z) = liftA3 (Node3 s) (traverseBlob w x) (traverseBlob w y) (traverseBlob w z)
501
+ #else
446
502
traverse _ (Seq EmptyT ) = pure (Seq EmptyT )
447
503
traverse f' (Seq (Single (Elem x'))) =
448
504
(\ x'' -> Seq (Single (Elem x''))) <$> f' x'
@@ -514,6 +570,7 @@ instance Traversable Seq where
514
570
:: Applicative f
515
571
=> (Node a -> f (Node b )) -> Node (Node a ) -> f (Node (Node b ))
516
572
traverseNodeN f t = traverse f t
573
+ #endif
517
574
518
575
instance NFData a => NFData (Seq a ) where
519
576
rnf (Seq xs) = rnf xs
@@ -1078,7 +1135,33 @@ instance Sized a => Sized (FingerTree a) where
1078
1135
size (Single x) = size x
1079
1136
size (Deep v _ _ _) = v
1080
1137
1138
+ -- We don't fold FingerTrees directly, but instead coerce them to
1139
+ -- Seqs and fold those. This seems backwards! Why do it? We certainly
1140
+ -- *could* fold FingerTrees directly, but we'd need a slightly different
1141
+ -- version of the Depth GADT to do so. While that's not a big deal,
1142
+ -- it is a bit annoying. Note: we need the current version of Depth
1143
+ -- to deal with the Sized issues for indexed folds.
1081
1144
instance Foldable FingerTree where
1145
+ #ifdef __GLASGOW_HASKELL__
1146
+ foldMap :: forall m a . Monoid m => (a -> m ) -> FingerTree a -> m
1147
+ foldMap f = foldMapFT Bottom
1148
+ where
1149
+ foldMapBlob :: Depth a t -> t -> m
1150
+ foldMapBlob Bottom a = f a
1151
+ foldMapBlob (Deeper w) (Node2 _ x y) = foldMapBlob w x <> foldMapBlob w y
1152
+ foldMapBlob (Deeper w) (Node3 _ x y z) = foldMapBlob w x <> foldMapBlob w y <> foldMapBlob w z
1153
+
1154
+ foldMapFT :: Depth a t -> FingerTree t -> m
1155
+ foldMapFT ! _ EmptyT = mempty
1156
+ foldMapFT w (Single t) = foldMapBlob w t
1157
+ foldMapFT w (Deep _ pr m sf) =
1158
+ foldMap (foldMapBlob w) pr
1159
+ <> foldMapFT (Deeper w) m
1160
+ <> foldMap (foldMapBlob w) sf
1161
+
1162
+ -- foldMap = coerce (foldMap :: (a -> m) -> Seq a -> m)
1163
+ {-# INLINABLE foldMap #-}
1164
+ #else
1082
1165
foldMap _ EmptyT = mempty
1083
1166
foldMap f' (Single x') = f' x'
1084
1167
foldMap f' (Deep _ pr' m' sf') =
@@ -1105,8 +1188,6 @@ instance Foldable FingerTree where
1105
1188
1106
1189
foldMapNodeN :: Monoid m => (Node a -> m ) -> Node (Node a ) -> m
1107
1190
foldMapNodeN f t = foldNode (<>) f t
1108
- #if __GLASGOW_HASKELL__
1109
- {-# INLINABLE foldMap #-}
1110
1191
#endif
1111
1192
1112
1193
foldr _ z' EmptyT = z'
@@ -1270,7 +1351,7 @@ foldDigit _ f (One a) = f a
1270
1351
foldDigit (<+>) f (Two a b) = f a <+> f b
1271
1352
foldDigit (<+>) f (Three a b c) = f a <+> f b <+> f c
1272
1353
foldDigit (<+>) f (Four a b c d) = f a <+> f b <+> f c <+> f d
1273
- {-# INLINE foldDigit #-}
1354
+ {-# INLINABLE foldDigit #-}
1274
1355
1275
1356
instance Foldable Digit where
1276
1357
foldMap = foldDigit mappend
@@ -3203,15 +3284,56 @@ foldWithIndexNode (<+>) f s (Node3 _ a b c) = f s a <+> f sPsa b <+> f sPsab c
3203
3284
-- element in the sequence.
3204
3285
--
3205
3286
-- @since 0.5.8
3206
- foldMapWithIndex :: Monoid m => (Int -> a -> m ) -> Seq a -> m
3287
+ foldMapWithIndex :: forall m a . Monoid m => (Int -> a -> m ) -> Seq a -> m
3288
+ #ifdef __GLASGOW_HASKELL__
3289
+ foldMapWithIndex f (Seq t) = foldMapWithIndexFT Bottom 0 t
3290
+ where
3291
+ foldMapWithIndexFT :: Depth (Elem a ) t -> Int -> FingerTree t -> m
3292
+ foldMapWithIndexFT ! _ ! _ EmptyT = mempty
3293
+ foldMapWithIndexFT d s (Single xs) = foldMapWithIndexBlob d s xs
3294
+ foldMapWithIndexFT d s (Deep _ pr m sf) = case depthSized d of { Sizzy ->
3295
+ foldWithIndexDigit (<>) (foldMapWithIndexBlob d) s pr <>
3296
+ foldMapWithIndexFT (Deeper d) sPspr m <>
3297
+ foldWithIndexDigit (<>) (foldMapWithIndexBlob d) sPsprm sf
3298
+ where
3299
+ ! sPspr = s + size pr
3300
+ ! sPsprm = sPspr + size m
3301
+ }
3302
+
3303
+ foldMapWithIndexBlob :: Depth (Elem a ) t -> Int -> t -> m
3304
+ foldMapWithIndexBlob Bottom k (Elem a) = f k a
3305
+ foldMapWithIndexBlob (Deeper yop) k (Node2 _s t1 t2) =
3306
+ foldMapWithIndexBlob yop k t1 <>
3307
+ foldMapWithIndexBlob yop (k + sizeBlob yop t1) t2
3308
+ foldMapWithIndexBlob (Deeper yop) k (Node3 _s t1 t2 t3) =
3309
+ foldMapWithIndexBlob yop k t1 <>
3310
+ foldMapWithIndexBlob yop (k + st1) t2 <>
3311
+ foldMapWithIndexBlob yop (k + st1t2) t3
3312
+ where
3313
+ st1 = sizeBlob yop t1
3314
+ st1t2 = st1 + sizeBlob yop t2
3315
+ {-# INLINABLE foldMapWithIndex #-}
3316
+
3317
+ data Sizzy a where
3318
+ Sizzy :: Sized a => Sizzy a
3319
+
3320
+ depthSized :: Depth (Elem a ) t -> Sizzy t
3321
+ depthSized Bottom = Sizzy
3322
+ depthSized (Deeper _) = Sizzy
3323
+
3324
+ sizeBlob :: Depth (Elem a ) t -> t -> Int
3325
+ sizeBlob Bottom = size
3326
+ sizeBlob (Deeper _) = size
3327
+
3328
+ #else
3207
3329
foldMapWithIndex f' (Seq xs') = foldMapWithIndexTreeE (lift_elem f') 0 xs'
3208
3330
where
3209
3331
lift_elem :: (Int -> a -> m ) -> (Int -> Elem a -> m )
3210
- #ifdef __GLASGOW_HASKELL__
3332
+ # ifdef __GLASGOW_HASKELL__
3211
3333
lift_elem g = coerce g
3212
- #else
3334
+ # else
3213
3335
lift_elem g = \ s (Elem a) -> g s a
3214
- #endif
3336
+ # endif
3215
3337
{-# INLINE lift_elem #-}
3216
3338
-- We have to specialize these functions by hand, unfortunately, because
3217
3339
-- GHC does not specialize until *all* instances are determined.
@@ -3250,9 +3372,6 @@ foldMapWithIndex f' (Seq xs') = foldMapWithIndexTreeE (lift_elem f') 0 xs'
3250
3372
3251
3373
foldMapWithIndexNodeN :: Monoid m => (Int -> Node a -> m ) -> Int -> Node (Node a ) -> m
3252
3374
foldMapWithIndexNodeN f i t = foldWithIndexNode (<>) f i t
3253
-
3254
- #if __GLASGOW_HASKELL__
3255
- {-# INLINABLE foldMapWithIndex #-}
3256
3375
#endif
3257
3376
3258
3377
-- | 'traverseWithIndex' is a version of 'traverse' that also offers
@@ -4997,3 +5116,7 @@ fromList2 n = execState (replicateA n (State ht))
4997
5116
where
4998
5117
ht (x: xs) = (xs, x)
4999
5118
ht [] = error " fromList2: short list"
5119
+
5120
+ {-# NOINLINE bongo #-}
5121
+ bongo :: Seq [a ] -> [a ]
5122
+ bongo xs = GHC.Exts. inline foldMap id xs
0 commit comments