Давайте сыграем в игру. Есть две сваи, которые мы собираемся использовать, состоящие из черных/белых односторонних чипов.Обновление нескольких подполей поля с использованием объектива ekmett's
data Pile = Pile { _blacks, _whites :: Int }
makeLenses ''Pile
data Game = Game { _pileA, _pileB :: Pile }
makeLenses ''Game
Действительно умный ход будет перевернуть черную фишку в свайном А, а белый чип - в свайном 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
предложений. там, наверное, все для потребностей у всех там прячется. Не то, что это плохо, конечно! но я хотел было также полное руководство включено.)
Что вам не нравится в варианте 2? Это не может быть намного более кратким, чем это, не так ли? – leftaroundabout
@leftaroundabout Мне не нравится, что мне приходилось использовать скобки, которые становятся неуклюжими, когда задействованы многострочные выражения - например, блоки «do» и дополнительные уровни вложенности. – Artyom
Я думаю, что это помогло бы, если бы вы показали какой-то грубый псевдокод, соответствующий тому, как будет выглядеть ваш идеальный синтаксис. –