讓我們玩一個遊戲。有兩堆我們要使用,包括黑色/白色雙面芯片。使用ekmett的鏡頭更新字段的多個子字段
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
優惠。有可能是一切爲了大家的需求藏匿在那裏。不,這是不好的,當然!但我希望也有一個完整的手冊包括在內。)
你不喜歡選項2?它不能比這更簡潔,可以嗎? – leftaroundabout
@leftaroundabout我不喜歡我不得不使用括號,當涉及到多行表達式時會變得笨拙 - 例如'do'塊和更高級別的嵌套。 – Artyom
我認爲如果你顯示一些粗略的僞代碼對應於你的理想語法,它會有所幫助。 –