镜头功能类似于`%~`但returns`Maybe`

Lens function similar to `%~` but returns `Maybe`

我想要一个类似于 %~ 的镜头函数,但需要一个 f 的函数 returns a Maybe,并且 returns a Just 更新后的值 f if f returns a Just,returns a Nothing if f returns一个Nothing.

这是一个例子:

{-# 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

有没有办法缩短updateFoo

updateFoo f = f & bar <someLensFunction> doubleIfOdd

您正在寻找 (%%~)

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