@@ -139,6 +139,7 @@ module Data.Sequence (
139
139
foldrWithIndex , -- :: (Int -> a -> b -> b) -> b -> Seq a -> b
140
140
-- * Transformations
141
141
mapWithIndex , -- :: (Int -> a -> b) -> Seq a -> Seq b
142
+ traverseWithIndex , -- :: Applicative f => (Int -> a -> f b) -> Seq a -> f (Seq b)
142
143
reverse , -- :: Seq a -> Seq a
143
144
-- ** Zips
144
145
zip , -- :: Seq a -> Seq b -> Seq (a, b)
@@ -209,6 +210,7 @@ import qualified GHC.Exts
209
210
import Data.Functor.Identity (Identity (.. ))
210
211
#endif
211
212
213
+ default ()
212
214
213
215
infixr 5 `consTree`
214
216
infixl 5 `snocTree`
@@ -1659,6 +1661,123 @@ mapWithIndex f' (Seq xs') = Seq $ mapWithIndexTree (\s (Elem a) -> Elem (f' s a)
1659
1661
#-}
1660
1662
#endif
1661
1663
1664
+ -- | 'traverseWithIndex' is a version of 'traverse' that also offers
1665
+ -- access to the index of each element.
1666
+ traverseWithIndex :: Applicative f => (Int -> a -> f b ) -> Seq a -> f (Seq b )
1667
+ traverseWithIndex f' (Seq xs') = Seq <$> traverseWithIndexTreeE (\ s (Elem a) -> Elem <$> f' s a) 0 xs'
1668
+ where
1669
+ -- We have to specialize these functions by hand, unfortunately, because
1670
+ -- GHC does not specialize until *all* instances are determined.
1671
+ -- If we tried to used the Sized trick, it would likely leak to runtime.
1672
+ traverseWithIndexTreeE :: Applicative f => (Int -> Elem a -> f b ) -> Int -> FingerTree (Elem a ) -> f (FingerTree b )
1673
+ traverseWithIndexTreeE _ s Empty = s `seq` pure Empty
1674
+ traverseWithIndexTreeE f s (Single xs) = Single <$> f s xs
1675
+ traverseWithIndexTreeE f s (Deep n pr m sf) = sPspr `seq` sPsprm `seq`
1676
+ Deep n <$>
1677
+ traverseWithIndexDigitE f s pr <*>
1678
+ traverseWithIndexTreeN (traverseWithIndexNodeE f) sPspr m <*>
1679
+ traverseWithIndexDigitE f sPsprm sf
1680
+ where
1681
+ sPspr = s + size pr
1682
+ sPsprm = s + n - size sf
1683
+
1684
+ traverseWithIndexTreeN :: Applicative f => (Int -> Node a -> f b ) -> Int -> FingerTree (Node a ) -> f (FingerTree b )
1685
+ traverseWithIndexTreeN _ s Empty = s `seq` pure Empty
1686
+ traverseWithIndexTreeN f s (Single xs) = Single <$> f s xs
1687
+ traverseWithIndexTreeN f s (Deep n pr m sf) = sPspr `seq` sPsprm `seq`
1688
+ Deep n <$>
1689
+ traverseWithIndexDigitN f s pr <*>
1690
+ traverseWithIndexTreeN (traverseWithIndexNodeN f) sPspr m <*>
1691
+ traverseWithIndexDigitN f sPsprm sf
1692
+ where
1693
+ sPspr = s + size pr
1694
+ sPsprm = s + n - size sf
1695
+
1696
+ traverseWithIndexDigitE :: Applicative f => (Int -> Elem a -> f b ) -> Int -> Digit (Elem a ) -> f (Digit b )
1697
+ traverseWithIndexDigitE f s (One a) = One <$> f s a
1698
+ traverseWithIndexDigitE f s (Two a b) = sPsa `seq` Two <$> f s a <*> f sPsa b
1699
+ where
1700
+ sPsa = s + size a
1701
+ traverseWithIndexDigitE f s (Three a b c) = sPsa `seq` sPsab `seq`
1702
+ Three <$> f s a <*> f sPsa b <*> f sPsab c
1703
+ where
1704
+ sPsa = s + size a
1705
+ sPsab = sPsa + size b
1706
+ traverseWithIndexDigitE f s (Four a b c d) = sPsa `seq` sPsab `seq` sPsabc `seq`
1707
+ Four <$> f s a <*> f sPsa b <*> f sPsab c <*> f sPsabc d
1708
+ where
1709
+ sPsa = s + size a
1710
+ sPsab = sPsa + size b
1711
+ sPsabc = sPsab + size c
1712
+
1713
+ traverseWithIndexDigitN :: Applicative f => (Int -> Node a -> f b ) -> Int -> Digit (Node a ) -> f (Digit b )
1714
+ traverseWithIndexDigitN f s (One a) = One <$> f s a
1715
+ traverseWithIndexDigitN f s (Two a b) = sPsa `seq` Two <$> f s a <*> f sPsa b
1716
+ where
1717
+ sPsa = s + size a
1718
+ traverseWithIndexDigitN f s (Three a b c) = sPsa `seq` sPsab `seq`
1719
+ Three <$> f s a <*> f sPsa b <*> f sPsab c
1720
+ where
1721
+ sPsa = s + size a
1722
+ sPsab = sPsa + size b
1723
+ traverseWithIndexDigitN f s (Four a b c d) = sPsa `seq` sPsab `seq` sPsabc `seq`
1724
+ Four <$> f s a <*> f sPsa b <*> f sPsab c <*> f sPsabc d
1725
+ where
1726
+ sPsa = s + size a
1727
+ sPsab = sPsa + size b
1728
+ sPsabc = sPsab + size c
1729
+
1730
+ traverseWithIndexNodeE :: Applicative f => (Int -> Elem a -> f b ) -> Int -> Node (Elem a ) -> f (Node b )
1731
+ traverseWithIndexNodeE f s (Node2 ns a b) = sPsa `seq` Node2 ns <$> f s a <*> f sPsa b
1732
+ where
1733
+ sPsa = s + size a
1734
+ traverseWithIndexNodeE f s (Node3 ns a b c) = sPsa `seq` sPsab `seq`
1735
+ Node3 ns <$> f s a <*> f sPsa b <*> f sPsab c
1736
+ where
1737
+ sPsa = s + size a
1738
+ sPsab = sPsa + size b
1739
+
1740
+ traverseWithIndexNodeN :: Applicative f => (Int -> Node a -> f b ) -> Int -> Node (Node a ) -> f (Node b )
1741
+ traverseWithIndexNodeN f s (Node2 ns a b) = sPsa `seq` Node2 ns <$> f s a <*> f sPsa b
1742
+ where
1743
+ sPsa = s + size a
1744
+ traverseWithIndexNodeN f s (Node3 ns a b c) = sPsa `seq` sPsab `seq`
1745
+ Node3 ns <$> f s a <*> f sPsa b <*> f sPsab c
1746
+ where
1747
+ sPsa = s + size a
1748
+ sPsab = sPsa + size b
1749
+
1750
+ {-# NOINLINE [1] traverseWithIndex #-}
1751
+ #ifdef __GLASGOW_HASKELL__
1752
+ {-# RULES
1753
+ "travWithIndex/mapWithIndex" forall f g xs . traverseWithIndex f (mapWithIndex g xs) =
1754
+ traverseWithIndex (\k a -> f k (g k a)) xs
1755
+ "travWithIndex/fmapSeq" forall f g xs . traverseWithIndex f (fmapSeq g xs) =
1756
+ traverseWithIndex (\k a -> f k (g a)) xs
1757
+ #-}
1758
+ #endif
1759
+ {-
1760
+ It might be nice to be able to rewrite
1761
+
1762
+ traverseWithIndex f (fromFunction i g)
1763
+ to
1764
+ replicateAWithIndex i (\k -> f k (g k))
1765
+ and
1766
+ traverse f (fromFunction i g)
1767
+ to
1768
+ replicateAWithIndex i (f . g)
1769
+
1770
+ but we don't have replicateAWithIndex as yet.
1771
+
1772
+ We might wish for a rule like
1773
+ "fmapSeq/travWithIndex" forall f g xs . fmapSeq f <$> traverseWithIndex g xs =
1774
+ traverseWithIndex (\k a -> f <$> g k a) xs
1775
+ Unfortunately, this rule could screw up the inliner's treatment of
1776
+ fmap in general, and it also relies on the arbitrary Functor being
1777
+ valid.
1778
+ -}
1779
+
1780
+
1662
1781
-- | /O(n)/. Convert a given sequence length and a function representing that
1663
1782
-- sequence into a sequence.
1664
1783
fromFunction :: Int -> (Int -> a ) -> Seq a
0 commit comments