有条件地修改镜头的目标
Modifying the target of a Lens conditionally
我有一个函数可以根据输入和棋盘生成更新的棋盘,前提是游戏规则允许移动:
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
仅当提供的函数 returns a Just
时。我找到了 ?~
运算符,但它处理左侧的偏向性。
是否有(可能更通用的)组合器可以实现这一点,或者是否有另一种方式以简洁和惯用的方式表达这一点?
你可以做到
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
并获得类型 GameState -> Maybe GameState
.
我有一个函数可以根据输入和棋盘生成更新的棋盘,前提是游戏规则允许移动:
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
仅当提供的函数 returns a Just
时。我找到了 ?~
运算符,但它处理左侧的偏向性。
是否有(可能更通用的)组合器可以实现这一点,或者是否有另一种方式以简洁和惯用的方式表达这一点?
你可以做到
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
并获得类型 GameState -> Maybe GameState
.