如果游戏规则允许移动,我有一个从输入和棋盘生成更新的棋盘的功能:
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
。我找到了?~
运算符,但是它处理了左侧的偏倚。
是否有一个(可能更通用的)组合器可以实现这一目标,还是有其他方式以简洁和惯用的方式表达这一点?
答案 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 b
是forall f . Functor f => (a -> f b) -> (s -> f t)
的类型别名这一事实,因此我们可以选择将Maybe
用作f
并获取类型{{1}的函数}}