Zagrajmy w grę. Są dwa stosy, które zamierzamy użyć, oba składające się z czarnych/białych jednostronnych żetonów.Aktualizowanie wielu subpól pola za pomocą soczewki ekmett's
data Pile = Pile { _blacks, _whites :: Int }
makeLenses ''Pile
data Game = Game { _pileA, _pileB :: Pile }
makeLenses ''Game
Naprawdę sprytnym posunięciem byłoby obrócenie czarnego żetonu w stosie A i białego żetonu - w stosie B. Ale jak?
cleverMove :: Game -> Game
cleverMove game = game & pileA . blacks -~ 1
& pileA . whites +~ 1
& pileB . blacks +~ 1
& pileB . whites -~ 1
Niezbyt elegancki. Jak mogę to zrobić bez dwukrotnego odniesienia do każdego stosu?
Jedyne co wymyśliłem (a ja się nie podoba):
cleverMove game = game & pileA %~ (blacks -~ 1)
. (whites +~ 1)
& pileB %~ (blacks +~ 1)
. (whites -~ 1)
(Przepraszam z góry jeżeli jest to oczywiste - Jestem trochę nowych do soczewek i czuję się zagubiony w morzu kombinatorów i operatorów lens
oferty. Nie ma chyba wszystko na potrzeby każdego z nas ukrywa tam. Nie dlatego, że to jest złe, oczywiście! ale szkoda, że nie było również kompletny podręcznik włączone.)
Czego nie lubisz w opcji 2? Nie może być bardziej zwięzła, prawda? – leftaroundabout
@leftaroundabout Nie podoba mi się to, że musiałem użyć nawiasów, które stają się niezdarne, gdy występują wyrażenia wielowierszowe - takie jak '' 'bloki i dalsze poziomy zagnieżdżania. – Artyom
Myślę, że to pomogłoby, gdybyś pokazał jakiś szorstki pseudo-kod odpowiadający idealnej składni. –