I'm looking for a version of .~
that takes a value wrapped in a Monad and returns a Monad. For example:
(0, 1) & _1 .~ 100 = (100,1)
Hypothetical .~~
would:
(0, 1) & _1 .~~ return 100 = return (100,1)
While it would not be hard to define, is it already defined somewhere in the Lens package?
I don't know about a single operator precisely like that, but with some "tiny" adjustments, this is essentially what the raw application of a lens does. The adjustments are:
Monad
needs to be a Functor
, as nearly all are. (This will be mandatory from GHC 7.10, but isn't quite yet in 7.8.)So you can do:
Prelude Control.Lens> (0,1) & _1 (const (Just 100))
Just (100,1)
Prelude Control.Lens> (0,1) & _1 (const [100])
[(100,1)]
Prelude Control.Lens> (0,1) & _1 (const [100,200])
[(100,1),(200,1)]
Even works with Traversals
:
Prelude Control.Lens> (0,1) & both (const [100,200])
[(100,100),(100,200),(200,100),(200,200)]
If you still want an operator too, the %%~
operator has been defined, but it's essentially a type-restricted synonym for id
:
Prelude Control.Lens> (0,1) & _1 %%~ const (return 100) :: Either () (Int,Int)
Right (100,1)
Finally, although you did say it was simple, your .~~
operator (which I think would logically be .%~
or the like if it were actually in lens
) can be defined as just
Prelude Control.Lens> let (.~~) = (. const)
Prelude Control.Lens> (0,1) & _1 .~~ return 100 :: Either () (Int,Int)
Right (100,1)