I want a lens function that is similar to %~
, but takes a function f
that returns a Maybe
, and returns a Just
with the updated value by f
if f
returns a Just
, and returns a Nothing
if f
returns a Nothing
.
Here's an example:
{-# LANGUAGE TemplateHaskell #-}
import Control.Lens (makeLenses, (%~), (&), (.~), (^.))
newtype Foo =
Foo
{ _bar :: Int
}
deriving (Show)
makeLenses ''Foo
updateFoo :: Foo -> Maybe Foo
updateFoo f = fmap (\x -> f & bar .~ x) $ doubleIfOdd $ f ^. bar
doubleIfOdd :: Int -> Maybe Int
doubleIfOdd x
| odd x = Just $ x * 2
| otherwise = Nothing
*Main> updateFoo (Foo 3)
Just (Foo {_bar = 6})
*Main> updateFoo (Foo 4)
Nothing
Is there a way to shorten updateFoo
?
updateFoo f = f & bar <someLensFunction> doubleIfOdd
CodePudding user response:
You're looking for (%%~)
.
ghci> (1,2) & _1 %%~ \x -> if odd x then Just (x * 2) else Nothing
Just (2,2)
ghci> (2,2) & _1 %%~ \x -> if odd x then Just (x * 2) else Nothing
Nothing