Home > Back-end >  Lens function similar to `%~` but returns `Maybe`
Lens function similar to `%~` but returns `Maybe`

Time:12-18

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
  • Related