Skip to content

Commit 3073091

Browse files
committed
Continuing fake GADT
Use in more functions, etc.
1 parent 311d13d commit 3073091

File tree

3 files changed

+113
-67
lines changed

3 files changed

+113
-67
lines changed

containers-tests/containers-tests.cabal

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ library
124124

125125
if impl(ghc)
126126
other-modules:
127+
Data.Sequence.Internal.Depth
127128
Utils.Containers.Internal.TypeError
128129

129130
if impl(ghc >= 8.6)

containers/containers.cabal

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ Library
7070
Data.Graph
7171
Data.Sequence
7272
Data.Sequence.Internal
73-
Data.Sequence.Internal.Depth
7473
Data.Sequence.Internal.Sorting
7574
Data.Tree
7675
Utils.Containers.Internal.BitUtil
@@ -85,6 +84,7 @@ Library
8584
Utils.Containers.Internal.EqOrdUtil
8685
if impl(ghc)
8786
other-modules:
87+
Data.Sequence.Internal.Depth
8888
Utils.Containers.Internal.TypeError
8989

9090
include-dirs: include

containers/src/Data/Sequence/Internal.hs

Lines changed: 111 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -388,19 +388,39 @@ instance Functor Seq where
388388
x <$ s = replicate (length s) x
389389
#endif
390390

391-
fmapSeq :: (a -> b) -> Seq a -> Seq b
392-
fmapSeq f (Seq xs) = Seq (fmap (fmap f) xs)
393391
#ifdef __GLASGOW_HASKELL__
392+
fmapSeq :: forall a b. (a -> b) -> Seq a -> Seq b
393+
fmapSeq f (Seq t0) = Seq (fmapFT Bottom2 t0)
394+
where
395+
fmapBlob :: Depth2 (Elem a) t (Elem b) u -> t -> u
396+
fmapBlob Bottom2 (Elem a) = Elem (f a)
397+
fmapBlob (Deeper2 w) (Node2 s x y) = Node2 s (fmapBlob w x) (fmapBlob w y)
398+
fmapBlob (Deeper2 w) (Node3 s x y z) = Node3 s (fmapBlob w x) (fmapBlob w y) (fmapBlob w z)
399+
400+
fmapFT :: Depth2 (Elem a) t (Elem b) u -> FingerTree t -> FingerTree u
401+
fmapFT !_ EmptyT = EmptyT
402+
fmapFT w (Single t) = Single (fmapBlob w t)
403+
fmapFT w (Deep s pr m sf) =
404+
Deep s
405+
(fmap (fmapBlob w) pr)
406+
(fmapFT (Deeper2 w) m)
407+
(fmap (fmapBlob w) sf)
408+
394409
{-# NOINLINE [1] fmapSeq #-}
395410
{-# RULES
396411
"fmapSeq/fmapSeq" forall f g xs . fmapSeq f (fmapSeq g xs) = fmapSeq (f . g) xs
397412
"fmapSeq/coerce" fmapSeq coerce = coerce
398413
#-}
414+
415+
#else
416+
fmapSeq :: (a -> b) -> Seq a -> Seq b
417+
fmapSeq f (Seq xs) = Seq (fmap (fmap f) xs)
399418
#endif
400419

401-
--type Depth = Depth_ Elem Node
420+
#ifdef __GLASGOW_HASKELL__
402421
type Depth = Depth_ Node
403422
type Depth2 = Depth2_ Node
423+
#endif
404424

405425
instance Foldable Seq where
406426
#ifdef __GLASGOW_HASKELL__
@@ -423,25 +443,32 @@ instance Foldable Seq where
423443
foldr :: forall a b. (a -> b -> b) -> b -> Seq a -> b
424444
-- We define this explicitly so we can inline the foldMap. And we don't
425445
-- define it as a coercion of the FingerTree version because we want users
426-
-- to have the option of (effectively) inlining it explicitly.
446+
-- to have the option of (effectively) inlining it explicitly. Should we
447+
-- define this by hand to associate optimally? Or is GHC clever enough to
448+
-- do that for us?
427449
foldr f z t = appEndo (GHC.Exts.inline foldMap (coerce f) t) z
428450

429451
foldl :: forall b a. (b -> a -> b) -> b -> Seq a -> b
430-
-- Should we define this by hand to associate optimally? Or is GHC
431-
-- clever enough to do that for us?
432452
foldl f z t = appEndo (getDual (GHC.Exts.inline foldMap (Dual . Endo . flip f) t)) z
433453

434454
foldr' :: forall a b. (a -> b -> b) -> b -> Seq a -> b
435-
foldr' = coerce (foldr' :: (Elem a -> b -> b) -> b -> FingerTree (Elem a) -> b)
455+
foldr' f z0 = \ xs ->
456+
GHC.Exts.inline foldl (\ (k::b->b) (x::a) -> GHC.Exts.oneShot (\ (z::b) -> z `seq` k (f x z)))
457+
(id::b->b) xs z0
436458

437459
foldl' :: forall b a. (b -> a -> b) -> b -> Seq a -> b
438-
foldl' = coerce (foldl' :: (b -> Elem a -> b) -> b -> FingerTree (Elem a) -> b)
460+
foldl' f z0 = \ xs ->
461+
GHC.Exts.inline foldr (\ (x::a) (k::b->b) -> GHC.Exts.oneShot (\ (z::b) -> z `seq` k (f z x)))
462+
(id::b->b) xs z0
439463

440464
foldr1 :: forall a. (a -> a -> a) -> Seq a -> a
441-
foldr1 = coerce (foldr1 :: (Elem a -> Elem a -> Elem a) -> FingerTree (Elem a) -> Elem a)
465+
foldr1 _f Empty = error "foldr1: empty sequence"
466+
foldr1 f (xs :|> x) = foldr f x xs
442467

443468
foldl1 :: forall a. (a -> a -> a) -> Seq a -> a
444-
foldl1 = coerce (foldl1 :: (Elem a -> Elem a -> Elem a) -> FingerTree (Elem a) -> Elem a)
469+
foldl1 _f Empty = error "foldl1: empty sequence"
470+
foldl1 f (x :<| xs) = foldl f x xs
471+
445472
#else
446473
foldMap f (Seq xs) = foldMap (f . getElem) xs
447474

@@ -1135,33 +1162,7 @@ instance Sized a => Sized (FingerTree a) where
11351162
size (Single x) = size x
11361163
size (Deep v _ _ _) = v
11371164

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.
11441165
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
11651166
foldMap _ EmptyT = mempty
11661167
foldMap f' (Single x') = f' x'
11671168
foldMap f' (Deep _ pr' m' sf') =
@@ -1188,8 +1189,11 @@ instance Foldable FingerTree where
11881189

11891190
foldMapNodeN :: Monoid m => (Node a -> m) -> Node (Node a) -> m
11901191
foldMapNodeN f t = foldNode (<>) f t
1192+
#if __GLASGOW_HASKELL__
1193+
{-# INLINABLE foldMap #-}
11911194
#endif
11921195

1196+
11931197
foldr _ z' EmptyT = z'
11941198
foldr f' z' (Single x') = x' `f'` z'
11951199
foldr f' z' (Deep _ pr' m' sf') =
@@ -3192,6 +3196,49 @@ delDigit f i (Four a b c d)
31923196
-- | A generalization of 'fmap', 'mapWithIndex' takes a mapping
31933197
-- function that also depends on the element's index, and applies it to every
31943198
-- element in the sequence.
3199+
#ifdef __GLASGOW_HASKELL__
3200+
mapWithIndex :: forall a b. (Int -> a -> b) -> Seq a -> Seq b
3201+
mapWithIndex f (Seq t) = Seq $ mapWithIndexFT Bottom2 0 t
3202+
where
3203+
mapWithIndexFT :: Depth2 (Elem a) t (Elem b) u -> Int -> FingerTree t -> FingerTree u
3204+
mapWithIndexFT !_ !_ EmptyT = EmptyT
3205+
mapWithIndexFT d s (Single xs) = Single $ mapWithIndexBlob d s xs
3206+
mapWithIndexFT d s (Deep s' pr m sf) = case depthSized2 d of { Sizzy ->
3207+
Deep s'
3208+
(mapWithIndexDigit (mapWithIndexBlob d) s pr)
3209+
(mapWithIndexFT (Deeper2 d) sPspr m)
3210+
(mapWithIndexDigit (mapWithIndexBlob d) sPsprm sf)
3211+
where
3212+
!sPspr = s + size pr
3213+
!sPsprm = sPspr + size m
3214+
}
3215+
3216+
mapWithIndexBlob :: Depth2 (Elem a) t (Elem b) u -> Int -> t -> u
3217+
mapWithIndexBlob Bottom2 k (Elem a) = Elem (f k a)
3218+
mapWithIndexBlob (Deeper2 yop) k (Node2 s t1 t2) =
3219+
Node2 s
3220+
(mapWithIndexBlob yop k t1)
3221+
(mapWithIndexBlob yop (k + sizeBlob2 yop t1) t2)
3222+
mapWithIndexBlob (Deeper2 yop) k (Node3 s t1 t2 t3) =
3223+
Node3 s
3224+
(mapWithIndexBlob yop k t1)
3225+
(mapWithIndexBlob yop (k + st1) t2)
3226+
(mapWithIndexBlob yop (k + st1t2) t3)
3227+
where
3228+
st1 = sizeBlob2 yop t1
3229+
st1t2 = st1 + sizeBlob2 yop t2
3230+
3231+
{-# NOINLINE [1] mapWithIndex #-}
3232+
3233+
{-# RULES
3234+
"mapWithIndex/mapWithIndex" forall f g xs . mapWithIndex f (mapWithIndex g xs) =
3235+
mapWithIndex (\k a -> f k (g k a)) xs
3236+
"mapWithIndex/fmapSeq" forall f g xs . mapWithIndex f (fmapSeq g xs) =
3237+
mapWithIndex (\k a -> f k (g a)) xs
3238+
"fmapSeq/mapWithIndex" forall f g xs . fmapSeq f (mapWithIndex g xs) =
3239+
mapWithIndex (\k a -> f (g k a)) xs
3240+
#-}
3241+
#else
31953242
mapWithIndex :: (Int -> a -> b) -> Seq a -> Seq b
31963243
mapWithIndex f' (Seq xs') = Seq $ mapWithIndexTree (\s (Elem a) -> Elem (f' s a)) 0 xs'
31973244
where
@@ -3209,25 +3256,6 @@ mapWithIndex f' (Seq xs') = Seq $ mapWithIndexTree (\s (Elem a) -> Elem (f' s a)
32093256
!sPspr = s + size pr
32103257
!sPsprm = sPspr + size m
32113258

3212-
{-# SPECIALIZE mapWithIndexDigit :: (Int -> Elem y -> b) -> Int -> Digit (Elem y) -> Digit b #-}
3213-
{-# SPECIALIZE mapWithIndexDigit :: (Int -> Node y -> b) -> Int -> Digit (Node y) -> Digit b #-}
3214-
mapWithIndexDigit :: Sized a => (Int -> a -> b) -> Int -> Digit a -> Digit b
3215-
mapWithIndexDigit f !s (One a) = One (f s a)
3216-
mapWithIndexDigit f s (Two a b) = Two (f s a) (f sPsa b)
3217-
where
3218-
!sPsa = s + size a
3219-
mapWithIndexDigit f s (Three a b c) =
3220-
Three (f s a) (f sPsa b) (f sPsab c)
3221-
where
3222-
!sPsa = s + size a
3223-
!sPsab = sPsa + size b
3224-
mapWithIndexDigit f s (Four a b c d) =
3225-
Four (f s a) (f sPsa b) (f sPsab c) (f sPsabc d)
3226-
where
3227-
!sPsa = s + size a
3228-
!sPsab = sPsa + size b
3229-
!sPsabc = sPsab + size c
3230-
32313259
{-# SPECIALIZE mapWithIndexNode :: (Int -> Elem y -> b) -> Int -> Node (Elem y) -> Node b #-}
32323260
{-# SPECIALIZE mapWithIndexNode :: (Int -> Node y -> b) -> Int -> Node (Node y) -> Node b #-}
32333261
mapWithIndexNode :: Sized a => (Int -> a -> b) -> Int -> Node a -> Node b
@@ -3239,19 +3267,28 @@ mapWithIndex f' (Seq xs') = Seq $ mapWithIndexTree (\s (Elem a) -> Elem (f' s a)
32393267
where
32403268
!sPsa = s + size a
32413269
!sPsab = sPsa + size b
3242-
3243-
#ifdef __GLASGOW_HASKELL__
3244-
{-# NOINLINE [1] mapWithIndex #-}
3245-
{-# RULES
3246-
"mapWithIndex/mapWithIndex" forall f g xs . mapWithIndex f (mapWithIndex g xs) =
3247-
mapWithIndex (\k a -> f k (g k a)) xs
3248-
"mapWithIndex/fmapSeq" forall f g xs . mapWithIndex f (fmapSeq g xs) =
3249-
mapWithIndex (\k a -> f k (g a)) xs
3250-
"fmapSeq/mapWithIndex" forall f g xs . fmapSeq f (mapWithIndex g xs) =
3251-
mapWithIndex (\k a -> f (g k a)) xs
3252-
#-}
32533270
#endif
32543271

3272+
{-# SPECIALIZE mapWithIndexDigit :: (Int -> Elem a -> b) -> Int -> Digit (Elem a) -> Digit b #-}
3273+
{-# SPECIALIZE mapWithIndexDigit :: (Int -> Node a -> b) -> Int -> Digit (Node a) -> Digit b #-}
3274+
mapWithIndexDigit :: Sized x => (Int -> x -> y) -> Int -> Digit x -> Digit y
3275+
mapWithIndexDigit f !s (One a) = One (f s a)
3276+
mapWithIndexDigit f s (Two a b) = Two (f s a) (f sPsa b)
3277+
where
3278+
!sPsa = s + size a
3279+
mapWithIndexDigit f s (Three a b c) =
3280+
Three (f s a) (f sPsa b) (f sPsab c)
3281+
where
3282+
!sPsa = s + size a
3283+
!sPsab = sPsa + size b
3284+
mapWithIndexDigit f s (Four a b c d) =
3285+
Four (f s a) (f sPsa b) (f sPsab c) (f sPsabc d)
3286+
where
3287+
!sPsa = s + size a
3288+
!sPsab = sPsa + size b
3289+
!sPsabc = sPsab + size c
3290+
3291+
32553292
{-# INLINE foldWithIndexDigit #-}
32563293
foldWithIndexDigit :: Sized a => (b -> b -> b) -> (Int -> a -> b) -> Int -> Digit a -> b
32573294
foldWithIndexDigit _ f !s (One a) = f s a
@@ -3321,10 +3358,18 @@ depthSized :: Depth (Elem a) t -> Sizzy t
33213358
depthSized Bottom = Sizzy
33223359
depthSized (Deeper _) = Sizzy
33233360

3361+
depthSized2 :: Depth2 (Elem a) t (Elem b) u -> Sizzy t
3362+
depthSized2 Bottom2 = Sizzy
3363+
depthSized2 (Deeper2 _) = Sizzy
3364+
33243365
sizeBlob :: Depth (Elem a) t -> t -> Int
33253366
sizeBlob Bottom = size
33263367
sizeBlob (Deeper _) = size
33273368

3369+
sizeBlob2 :: Depth2 (Elem a) t (Elem b) u -> t -> Int
3370+
sizeBlob2 Bottom2 = size
3371+
sizeBlob2 (Deeper2 _) = size
3372+
33283373
#else
33293374
foldMapWithIndex f' (Seq xs') = foldMapWithIndexTreeE (lift_elem f') 0 xs'
33303375
where

0 commit comments

Comments
 (0)