5

I need a function like <<%~ which would act with Traversals in similar fashion to ^?, like this:

(<<?%~) :: Traversal s t a b -> (a -> b) -> s -> (Maybe a, t)

> ix 0 <<?%~ succ $ [1,2]
(Just 1,[2,2])
> ix 1 <<?%~ succ $ [1,2]
(Just 2,[1,3])
> ix 2 <<?%~ succ $ [1,2]
(Nothing,[1,2])

How should I implement it? The obvious way is to apply ^? and %~ separately, but I'd like a solution in one go.

modular
  • 1,099
  • 9
  • 22

1 Answers1

4

If we don't want to require a Monoid constraint on the targets, we have to specify ourselves the Monoid that will be used for combining the old elements in a traversal. As the goal is something analogous to ^?, the appropriate monoid is First.

(<<?%~) :: LensLike ((,) (First a)) s t a b -> (a -> b) -> s -> (Maybe a, t)
l <<?%~ f = first getFirst . (l $ \a -> (First (Just a), f a))
duplode
  • 33,731
  • 7
  • 79
  • 150
modular
  • 1,099
  • 9
  • 22
  • 3
    I changed the framing around your solution rather drastically. Feel free to revert the changes if you don't like them. – duplode Oct 12 '16 at 02:15