Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 25 additions & 23 deletions indexed-traversable/src/Data/Foldable/WithIndex.hs
Original file line number Diff line number Diff line change
Expand Up @@ -41,18 +41,18 @@ import WithIndex
-- When you don't need access to the index then 'any' is more flexible in what it accepts.
--
-- @
-- 'any' ≡ 'iany' '.' 'const'
-- 'any' ≡ 'iany' '.' 'Data.Function.const'
-- @
iany :: FoldableWithIndex i f => (i -> a -> Bool) -> f a -> Bool
iany f = getAny #. ifoldMap (Any #.. f)
{-# INLINE iany #-}

-- | Return whether or not all elements in a container satisfy a predicate, with access to the index @i@.
--
-- When you don't need access to the index then 'all' is more flexible in what it accepts.
-- When you don't need access to the index then 'Data.Foldable.all' is more flexible in what it accepts.
--
-- @
-- 'all' ≡ 'iall' '.' 'const'
-- 'Data.Foldable.all' ≡ 'iall' '.' 'Data.Function.const'
-- @
iall :: FoldableWithIndex i f => (i -> a -> Bool) -> f a -> Bool
iall f = getAll #. ifoldMap (All #.. f)
Expand All @@ -63,7 +63,7 @@ iall f = getAll #. ifoldMap (All #.. f)
-- When you don't need access to the index then 'none' is more flexible in what it accepts.
--
-- @
-- 'none' ≡ 'inone' '.' 'const'
-- 'none' ≡ 'inone' '.' 'Data.Function.const'
-- 'inone' f ≡ 'not' '.' 'iany' f
-- @
inone :: FoldableWithIndex i f => (i -> a -> Bool) -> f a -> Bool
Expand All @@ -81,10 +81,10 @@ none f = not . any f

-- | Traverse elements with access to the index @i@, discarding the results.
--
-- When you don't need access to the index then 'traverse_' is more flexible in what it accepts.
-- When you don't need access to the index then 'Data.Foldable.traverse_' is more flexible in what it accepts.
--
-- @
-- 'traverse_' l = 'itraverse' '.' 'const'
-- 'Data.Foldable.traverse_' l = 'itraverse' '.' 'Data.Function.const'
-- @
itraverse_ :: (FoldableWithIndex i t, Applicative f) => (i -> a -> f b) -> t a -> f ()
itraverse_ f = void . getTraversed #. ifoldMap (Traversed #.. f)
Expand All @@ -96,28 +96,30 @@ itraverse_ f = void . getTraversed #. ifoldMap (Traversed #.. f)
-- 'ifor_' ≡ 'flip' 'itraverse_'
-- @
--
-- When you don't need access to the index then 'for_' is more flexible in what it accepts.
-- When you don't need access to the index then 'Data.Foldable.for_' is more flexible in what it accepts.
--
-- @
-- 'for_' a ≡ 'ifor_' a '.' 'const'
-- 'Data.Foldable.for_' a ≡ 'ifor_' a '.' 'Data.Function.const'
-- @
ifor_ :: (FoldableWithIndex i t, Applicative f) => t a -> (i -> a -> f b) -> f ()
ifor_ = flip itraverse_
{-# INLINE ifor_ #-}

-- | Run monadic actions for each target of an 'IndexedFold' or 'Control.Lens.IndexedTraversal.IndexedTraversal' with access to the index,
-- | Run monadic actions for each target of an 'ControlLens.Fold.IndexedFold' or 'Control.Lens.IndexedTraversal.IndexedTraversal' with
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aren't these new links broken too, as there is no dependency on lens anywhere near?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes you're right, there's no warning emitted by Haddock but the links are broken. I'll rewrite this to remove references to lens.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I rewrote that documentation to remove the references to lens.

I also fixed another warning emitted by Haddock 2.30.0 by disambiguating type/constructor puns (previously I was testing with Haddock 2.29.2)

-- access to the index,
-- discarding the results.
--
-- When you don't need access to the index then 'Control.Lens.Fold.mapMOf_' is more flexible in what it accepts.
-- When you don't need access to the index then 'Data.Foldable.mapM_' is more flexible in what it accepts.
--
-- @
-- 'mapM_' ≡ 'imapM' '.' 'const'
-- 'Data.Foldable.mapM_' ≡ 'imapM_' '.' 'Data.Function.const'
-- @
imapM_ :: (FoldableWithIndex i t, Monad m) => (i -> a -> m b) -> t a -> m ()
imapM_ f = liftM skip . getSequenced #. ifoldMap (Sequenced #.. f)
{-# INLINE imapM_ #-}

-- | Run monadic actions for each target of an 'IndexedFold' or 'Control.Lens.IndexedTraversal.IndexedTraversal' with access to the index,
-- | Run monadic actions for each target of an 'Control.Lens.Fold.IndexedFold' or 'Control.Lens.IndexedTraversal.IndexedTraversal' with
-- access to the index,
-- discarding the results (with the arguments flipped).
--
-- @
Expand All @@ -127,18 +129,18 @@ imapM_ f = liftM skip . getSequenced #. ifoldMap (Sequenced #.. f)
-- When you don't need access to the index then 'Control.Monad.forM_' is more flexible in what it accepts.
--
-- @
-- 'Control.Monad.forM_' a ≡ 'iforM' a '.' 'const'
-- 'Control.Monad.forM_' a ≡ 'iforM_' a '.' 'Data.Function.const'
-- @
iforM_ :: (FoldableWithIndex i t, Monad m) => t a -> (i -> a -> m b) -> m ()
iforM_ = flip imapM_
{-# INLINE iforM_ #-}

-- | Concatenate the results of a function of the elements of an indexed container with access to the index.
--
-- When you don't need access to the index then 'concatMap' is more flexible in what it accepts.
-- When you don't need access to the index then 'Data.Foldable.concatMap' is more flexible in what it accepts.
--
-- @
-- 'concatMap' ≡ 'iconcatMap' '.' 'const'
-- 'Data.Foldable.concatMap' ≡ 'iconcatMap' '.' 'Data.Function.const'
-- 'iconcatMap' ≡ 'ifoldMap'
-- @
iconcatMap :: FoldableWithIndex i f => (i -> a -> [b]) -> f a -> [b]
Expand All @@ -148,21 +150,21 @@ iconcatMap = ifoldMap
-- | Searches a container with a predicate that is also supplied the index, returning the left-most element of the structure
-- matching the predicate, or 'Nothing' if there is no such element.
--
-- When you don't need access to the index then 'find' is more flexible in what it accepts.
-- When you don't need access to the index then 'Data.Foldable.find' is more flexible in what it accepts.
--
-- @
-- 'find' ≡ 'ifind' '.' 'const'
-- 'Data.Foldable.find' ≡ 'ifind' '.' 'Data.Function.const'
-- @
ifind :: FoldableWithIndex i f => (i -> a -> Bool) -> f a -> Maybe (i, a)
ifind p = ifoldr (\i a y -> if p i a then Just (i, a) else y) Nothing
{-# INLINE ifind #-}

-- | Monadic fold right over the elements of a structure with an index.
--
-- When you don't need access to the index then 'foldrM' is more flexible in what it accepts.
-- When you don't need access to the index then 'Data.Foldable.foldrM' is more flexible in what it accepts.
--
-- @
-- 'foldrM' ≡ 'ifoldrM' '.' 'const'
-- 'Data.Foldable.foldrM' ≡ 'ifoldrM' '.' 'Data.Function.const'
-- @
ifoldrM :: (FoldableWithIndex i f, Monad m) => (i -> a -> b -> m b) -> b -> f a -> m b
ifoldrM f z0 xs = ifoldl f' return xs z0
Expand All @@ -171,10 +173,10 @@ ifoldrM f z0 xs = ifoldl f' return xs z0

-- | Monadic fold over the elements of a structure with an index, associating to the left.
--
-- When you don't need access to the index then 'foldlM' is more flexible in what it accepts.
-- When you don't need access to the index then 'Data.Foldable.foldlM' is more flexible in what it accepts.
--
-- @
-- 'foldlM' ≡ 'ifoldlM' '.' 'const'
-- 'Data.Foldable.foldlM' ≡ 'ifoldlM' '.' 'Data.Function.const'
-- @
ifoldlM :: (FoldableWithIndex i f, Monad m) => (i -> b -> a -> m b) -> b -> f a -> m b
ifoldlM f z0 xs = ifoldr f' return xs z0
Expand All @@ -183,10 +185,10 @@ ifoldlM f z0 xs = ifoldr f' return xs z0

-- | Extract the key-value pairs from a structure.
--
-- When you don't need access to the indices in the result, then 'toList' is more flexible in what it accepts.
-- When you don't need access to the indices in the result, then 'Data.Foldable.toList' is more flexible in what it accepts.
--
-- @
-- 'toList' ≡ 'Data.List.map' 'snd' '.' 'itoList'
-- 'Data.Foldable.toList' ≡ 'Data.List.map' 'Data.Tuple.snd' '.' 'itoList'
-- @
itoList :: FoldableWithIndex i f => f a -> [(i,a)]
itoList xs = build (\c n -> ifoldr (curry c) n xs)
Expand Down
2 changes: 1 addition & 1 deletion indexed-traversable/src/Data/Foldable1/WithIndex.hs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#endif
-- | Indexed non-empty Foldables.
module Data.Foldable1.WithIndex (
-- * Indexed Foldables
-- * Indexed non-empty Foldables
Foldable1WithIndex (..),
) where

Expand Down
1 change: 1 addition & 0 deletions indexed-traversable/src/Data/Functor/WithIndex.hs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#elif __GLASGOW_HASKELL__ >= 702
{-# LANGUAGE Trustworthy #-}
#endif
-- | Indexed Functors.
module Data.Functor.WithIndex (
-- * Indexed Functors
FunctorWithIndex(..),
Expand Down
12 changes: 6 additions & 6 deletions indexed-traversable/src/Data/Traversable/WithIndex.hs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import CoerceCompat
-- | Traverse with an index (and the arguments flipped).
--
-- @
-- 'for' a ≡ 'ifor' a '.' 'const'
-- 'Data.Traversable.for' a ≡ 'ifor' a 'Data.Function..' 'Data.Function.const'
-- 'ifor' ≡ 'flip' 'itraverse'
-- @
ifor :: (TraversableWithIndex i t, Applicative f) => t a -> (i -> a -> f b) -> f (t b)
Expand All @@ -44,10 +44,10 @@ ifor = flip itraverse
-- evaluate these actions from left to right, and collect the results, with access
-- the index.
--
-- When you don't need access to the index 'mapM' is more liberal in what it can accept.
-- When you don't need access to the index 'Data.Traversable.mapM' is more liberal in what it can accept.
--
-- @
-- 'mapM' ≡ 'imapM' '.' 'const'
-- 'Data.Traversable.mapM' ≡ 'imapM' 'Data.Function..' 'Data.Function.const'
-- @
imapM :: (TraversableWithIndex i t, Monad m) => (i -> a -> m b) -> t a -> m (t b)
imapM f = unwrapMonad #. itraverse (WrapMonad #.. f)
Expand All @@ -58,7 +58,7 @@ imapM f = unwrapMonad #. itraverse (WrapMonad #.. f)
-- its position (and the arguments flipped).
--
-- @
-- 'forM' a ≡ 'iforM' a '.' 'const'
-- 'Data.Traversable.forM' a ≡ 'iforM' a 'Data.Function..' 'Data.Function.const'
-- 'iforM' ≡ 'flip' 'imapM'
-- @
iforM :: (TraversableWithIndex i t, Monad m) => t a -> (i -> a -> m b) -> m (t b)
Expand All @@ -70,7 +70,7 @@ iforM = flip imapM
-- 'imapAccumR' accumulates state from right to left.
--
-- @
-- 'Data.Traversable.mapAccumR' ≡ 'imapAccumR' '.' 'const'
-- 'Data.Traversable.mapAccumR' ≡ 'imapAccumR' 'Data.Function..' 'Data.Function.const'
-- @
imapAccumR :: TraversableWithIndex i t => (i -> s -> a -> (s, b)) -> s -> t a -> (s, t b)
imapAccumR f s0 a = swap (Lazy.runState (forwards (itraverse (\i c -> Backwards (Lazy.state (\s -> swap (f i s c)))) a)) s0)
Expand All @@ -81,7 +81,7 @@ imapAccumR f s0 a = swap (Lazy.runState (forwards (itraverse (\i c -> Backwards
-- 'imapAccumL' accumulates state from left to right.
--
-- @
-- 'Data.Traversable.mapAccumL' ≡ 'imapAccumL' '.' 'const'
-- 'Data.Traversable.mapAccumL' ≡ 'imapAccumL' 'Data.Function..' 'Data.Function.const'
-- @
imapAccumL :: TraversableWithIndex i t => (i -> s -> a -> (s, b)) -> s -> t a -> (s, t b)
imapAccumL f s0 a = swap (Lazy.runState (itraverse (\i c -> Lazy.state (\s -> swap (f i s c))) a) s0)
Expand Down
28 changes: 14 additions & 14 deletions indexed-traversable/src/WithIndex.hs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ class Foldable f => FoldableWithIndex i f | f -> i where
-- When you don't need access to the index then 'foldMap' is more flexible in what it accepts.
--
-- @
-- 'foldMap' ≡ 'ifoldMap' '.' 'const'
-- 'foldMap' ≡ 'ifoldMap' '.' 'Data.Function.const'
-- @
ifoldMap :: Monoid m => (i -> a -> m) -> f a -> m

Expand All @@ -106,7 +106,7 @@ class Foldable f => FoldableWithIndex i f | f -> i where
-- When you don't need access to the index then 'Data.Foldable.foldMap'' is more flexible in what it accepts.
--
-- @
-- 'foldMap'' ≡ 'ifoldMap'' '.' 'const'
-- 'foldMap'' ≡ 'ifoldMap'' '.' 'Data.Function.const'
-- @
ifoldMap' :: Monoid m => (i -> a -> m) -> f a -> m
ifoldMap' f = ifoldl' (\i acc a -> mappend acc (f i a)) mempty
Expand All @@ -117,7 +117,7 @@ class Foldable f => FoldableWithIndex i f | f -> i where
-- When you don't need access to the index then 'Data.Foldable.foldr' is more flexible in what it accepts.
--
-- @
-- 'Data.Foldable.foldr' ≡ 'ifoldr' '.' 'const'
-- 'Data.Foldable.foldr' ≡ 'ifoldr' '.' 'Data.Function.const'
-- @
ifoldr :: (i -> a -> b -> b) -> b -> f a -> b
ifoldr f z t = appEndo (ifoldMap (Endo #.. f) t) z
Expand All @@ -128,7 +128,7 @@ class Foldable f => FoldableWithIndex i f | f -> i where
-- When you don't need access to the index then 'Data.Foldable.foldl' is more flexible in what it accepts.
--
-- @
-- 'Data.Foldable.foldl' ≡ 'ifoldl' '.' 'const'
-- 'Data.Foldable.foldl' ≡ 'ifoldl' '.' 'Data.Function.const'
-- @
ifoldl :: (i -> b -> a -> b) -> b -> f a -> b
ifoldl f z t = appEndo (getDual (ifoldMap (\ i -> Dual #. Endo #. flip (f i)) t)) z
Expand All @@ -139,7 +139,7 @@ class Foldable f => FoldableWithIndex i f | f -> i where
-- When you don't need access to the index then 'foldr'' is more flexible in what it accepts.
--
-- @
-- 'foldr'' ≡ 'ifoldr'' '.' 'const'
-- 'foldr'' ≡ 'ifoldr'' '.' 'Data.Function.const'
-- @
ifoldr' :: (i -> a -> b -> b) -> b -> f a -> b
ifoldr' f z0 xs = ifoldl f' id xs z0
Expand All @@ -151,7 +151,7 @@ class Foldable f => FoldableWithIndex i f | f -> i where
-- When you don't need access to the index then 'Control.Lens.Fold.foldlOf'' is more flexible in what it accepts.
--
-- @
-- 'Data.Foldable.foldl'' l ≡ 'ifoldl'' l '.' 'const'
-- 'Data.Foldable.foldl'' l ≡ 'ifoldl'' l '.' 'Data.Function.const'
-- @
ifoldl' :: (i -> b -> a -> b) -> b -> f a -> b
ifoldl' f z0 xs = ifoldr f' id xs z0
Expand All @@ -176,15 +176,15 @@ class (Foldable1 f, FoldableWithIndex i f) => Foldable1WithIndex i f | f -> i wh
ifoldMap1' :: Semigroup m => (i -> a -> m) -> f a -> m
ifoldMap1' f = ifoldlMap1' f (\i m a -> m <> f i a)

-- | Generalized 'ifoldr1'.
-- | Generalized @ifoldr1@.
ifoldrMap1 :: (i -> a -> b) -> (i -> a -> b -> b) -> f a -> b
ifoldrMap1 f g xs =
appFromMaybe (ifoldMap1 (FromMaybe #.. h) xs) Nothing
where
h i a Nothing = f i a
h i a (Just b) = g i a b

-- | Generalized 'ifoldl1''.
-- | Generalized @ifoldl1'@.
ifoldlMap1' :: (i -> a -> b) -> (i -> b -> a -> b) -> f a -> b
ifoldlMap1' f g xs =
ifoldrMap1 f' g' xs SNothing
Expand All @@ -197,15 +197,15 @@ class (Foldable1 f, FoldableWithIndex i f) => Foldable1WithIndex i f | f -> i wh
g' i a x SNothing = x $! SJust (f i a)
g' i a x (SJust b) = x $! SJust (g i b a)

-- | Generalized 'ifoldl1'.
-- | Generalized @ifoldl1@.
ifoldlMap1 :: (i -> a -> b) -> (i -> b -> a -> b) -> f a -> b
ifoldlMap1 f g xs =
appFromMaybe (getDual (ifoldMap1 ((Dual . FromMaybe) #.. h) xs)) Nothing
where
h i a Nothing = f i a
h i a (Just b) = g i b a

-- | Generalized 'ifoldr1''.
-- | Generalized @ifoldr1'@.
ifoldrMap1' :: (i -> a -> b) -> (i -> a -> b -> b) -> f a -> b
ifoldrMap1' f g xs =
ifoldlMap1 f' g' xs SNothing
Expand All @@ -227,14 +227,14 @@ class (Foldable1 f, FoldableWithIndex i f) => Foldable1WithIndex i f | f -> i wh
-- An instance must satisfy a (modified) form of the 'Traversable' laws:
--
-- @
-- 'itraverse' ('const' 'Identity') ≡ 'Identity'
-- 'itraverse' ('Data.Function.const' 'Identity') ≡ 'Identity'
-- 'fmap' ('itraverse' f) '.' 'itraverse' g ≡ 'Data.Functor.Compose.getCompose' '.' 'itraverse' (\\i -> 'Data.Functor.Compose.Compose' '.' 'fmap' (f i) '.' g i)
-- @
class (FunctorWithIndex i t, FoldableWithIndex i t, Traversable t) => TraversableWithIndex i t | t -> i where
-- | Traverse an indexed container.
--
-- @
-- 'itraverse' ≡ 'itraverseOf' 'itraversed'
-- 'itraverse' ≡ 'Control.Lens.Traversal.itraverseOf' 'Control.Lens.Indexed.itraversed'
-- @
itraverse :: Applicative f => (i -> a -> f b) -> t a -> f (t b)

Expand Down Expand Up @@ -674,7 +674,7 @@ skip _ = ()

-- | Used internally by 'Control.Lens.Traversal.traverseOf_' and the like.
--
-- The argument 'a' of the result should not be used!
-- The argument @a@ of the result should not be used!
newtype Traversed a f = Traversed { getTraversed :: f a }

-- See 4.16 Changelog entry for the explanation of "why not Apply f =>"?
Expand All @@ -694,7 +694,7 @@ instance Applicative f => Monoid (Traversed a f) where

-- | Used internally by 'Control.Lens.Traversal.mapM_' and the like.
--
-- The argument 'a' of the result should not be used!
-- The argument @a@ of the result should not be used!
--
-- See 4.16 Changelog entry for the explanation of "why not Apply f =>"?
newtype Sequenced a m = Sequenced { getSequenced :: m a }
Expand Down