This is quite complicated considering the current publicly open API.
I took the liberty of expanding the deepOf type to support indexed folds and indexed traversals along the way, as it was easier than not doing this, and makes the implementation complete, which we want to export from lens , anyway.
Let me import lens parts that we usually don’t show to users.
{-# LANGUAGE RankNTypes #-} import Control.Applicative import Control.Lens import Control.Lens.Internal.Bazaar import Control.Lens.Internal.Context import Control.Lens.Traversal import Control.Monad.State import Data.Profunctor.Rep import Data.Profunctor.Unsafe
We will need some internal combinators that we do not set from Control.Lens.Traversal , which are used to control Traversal / Fold like BazaarT and reset the answer.
pins :: (Bizarre pw, Corepresentable p) => wabt -> [Corep pa] pins = getConst
Now that we have this, we will build the correct version of deep .
-- | -- @ -- 'deep' :: 'Plated' s => 'Fold' sa -> 'Fold' sa -- 'deep' :: 'Plated' s => 'Traversal' ssab -> 'Traversal' ssab -- 'deep' :: 'Plated' s => 'IndexedFold' isa -> 'IndexedFold' isa -- 'deep' :: 'Plated' s => 'IndexedTraversal' ssab -> 'Traversal' issab -- @ deep :: (Plated s, Conjoined p, Applicative f) => Traversing pfssab -> Over pfssab deep = deepOf plate -- | -- @ -- 'deepOf' :: 'Fold ss' -> 'Fold' sa -> 'Fold' sa -- 'deepOf' :: 'Traversal' ss' -> 'Traversal' ssab -> 'Traversal' ssab -- 'deepOf' :: 'Fold ss' -> 'IndexedFold' isa -> 'IndexedFold' isa -- 'deepOf' :: 'Traversal' ss' -> 'IndexedTraversal' ssab -> 'Traversal' issab -- @ deepOf :: (Plated s, Conjoined p, Applicative f) => LensLike' fss -> Traversing pfssab -> Over pfssab deepOf rl pafb s = case pins b of [] -> r (deep l pafb) s xs -> unsafeOuts b <$> traverse (corep pafb) xs where b = l sell s
The feelings of deepOf very similar to the existing failing guts that you rightfully tried to use as a workhorse.
failing :: (Conjoined p, Applicative f) => Traversing pfstab -> Traversing pfstab -> Over pfstab failing lr pafb s = case pins b of [] -> runBazaarT (r sell s) pafb xs -> unsafeOuts b <$> traverse (corep pafb) xs where b = l sell s
The only difference is the case [], where instead of falling, we do all the nested Traversal .
I just checked this and haven't completed it, but it looks right.
Feel free to ask the question http://github.com/ekmett/lens/issues to add these combinators (or rename them), they probably belong to the lens API core so that code like this does not reach users, time as in the library itself is trivial to implement.
This is the code that we are trying to write once, so end users don’t need it.