6

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

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)

但是,我想知道是否有一个组合器 Lens仅在提供的函数返回 a 时才修改 a 的目标Just。我找到了?~操作员,但它在左侧处理了偏袒。

是否有一个(可能更通用的)组合器可以实现这一点,或者是否有另一种方式以简洁和惯用的方式表达这一点?

4

1 回答 1

6

你可以做

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),因此我们可以选择使用Maybeasf并获取类型的函数GameState -> Maybe GameState

于 2015-01-16T19:41:48.873 回答