来玩个游戏。我们将使用两堆,都由黑/白边的芯片组成。
data Pile = Pile { _blacks, _whites :: Int }
makeLenses ''Pile
data Game = Game { _pileA, _pileB :: Pile }
makeLenses ''Game
一个非常聪明的举动是在 A 堆中翻出黑色筹码,在 B 堆中翻出白色筹码。但是怎么做呢?
cleverMove :: Game -> Game
cleverMove game = game & pileA . blacks -~ 1
& pileA . whites +~ 1
& pileB . blacks +~ 1
& pileB . whites -~ 1
不是很优雅。如果不引用每个桩两次,我怎么能做到这一点?
我想出的唯一一件事(我不喜欢它):
cleverMove game = game & pileA %~ (blacks -~ 1)
. (whites +~ 1)
& pileB %~ (blacks +~ 1)
. (whites -~ 1)
(如果很明显,请提前抱歉 - 我对镜头有点陌生,我在组合器和操作员lens
的报价中迷失了方向。可能每个人都需要的东西都藏在那里。当然不是说这很糟糕!但我希望有还包括完整的手册。)