Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Modifying the target of a Lens conditionally

I have a function that produces an updated board from an input and a board, if the move is permitted by the rules of the game:

move :: Input -> Board -> Maybe Board

The board is wrapped in the GameState type with some additional data:

type GameState = (Board, ...)

Now I'd like to use lenses to update the board in the game state if move yields Just a value. I can do this with a helper function:

updateGameState :: Input -> GameState -> GameState
updateGameState input gs = gs & _1 %~ (f $ move input)
  where
    f g x = maybe x id (g x)

However, I'm wondering if there is a combinator that modifies the target of a Lens only if the supplied function returns a Just. I've found the ?~ operator, but that handles partiality on the left hand side.

Is there a (likely more general) combinator that can achieve this, or is there another way to express this in a terse and idiomatic way?

like image 981
vtan Avatar asked Jan 16 '15 19:01

vtan


People also ask

What is conditional mode change?

For example, let's say you're going to record an action that requires all files to be in RGB mode. Including Conditional Mode Change in the action ensures that all the files are actually converted—if necessary—to RGB mode. Choose File > Automate > Conditional Mode Change to display a dialog of settings (Figure 1.10).

WHAT IS lens correction in Photoshop?

Search. Last updated on Oct 6, 2021. The Lens correction tool fixes lens issues such as distortion and perspective. Since each lens is uniquely designed, the lens corrections are applied depending upon your lens model.

What is distortion in Photoshop?

What Is the Distort Tool? The Distort tool in Photoshop allows you to straighten a rectangular object in a photo taken at an angle. You can also use it to skew a graphic or artwork to fit the side of a packaging or box.


1 Answers

You could do

import Control.Applicative
import Data.Maybe

updateGameState :: Input -> GameState -> GameState
updateGameState input = fromMaybe <*> _1 (move input)
-- updateGameState x s = fromMaybe s $ _1 $ move x

This uses the fact that Lens s t a b is a type alias for forall f . Functor f => (a -> f b) -> (s -> f t), so we can choose to use Maybe as f and get a function of type GameState -> Maybe GameState.

like image 159
felix-eku Avatar answered Sep 27 '22 20:09

felix-eku