有条件地修改镜头的目标

时间:2015-01-16 19:23:07

标签: haskell lens lenses

如果游戏规则允许移动,我有一个从输入和棋盘生成更新的棋盘的功能:

move :: Input -> Board -> Maybe Board

电路板包含在GameState类型中,附带一些额外数据:

type GameState = (Board, ...)

现在,如果move产生Just值,我想使用镜头更新游戏状态下的棋盘。 我可以用辅助函数来做到这一点:

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

但是,我想知道是否有一个组合器可以修改a的目标 仅当提供的函数返回Lens时才Just。我找到了?~运算符,但是它处理了左侧的偏倚。

是否有一个(可能更通用的)组合器可以实现这一目标,还是有其他方式以简洁和惯用的方式表达这一点?

1 个答案:

答案 0 :(得分:5)

你可以做到

import Control.Applicative
import Data.Maybe

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

这使用Lens s t a bforall f . Functor f => (a -> f b) -> (s -> f t)的类型别名这一事实,因此我们可以选择将Maybe用作f并获取类型{{1}的函数}}