Hãy chơi trò chơi. Có hai đống chúng tôi sẽ sử dụng, cả hai đều bao gồm các chip màu đen/trắng.Cập nhật nhiều trường con của trường bằng cách sử dụng Ống kính ekmett
data Pile = Pile { _blacks, _whites :: Int }
makeLenses ''Pile
data Game = Game { _pileA, _pileB :: Pile }
makeLenses ''Game
Một động thái thực sự thông minh sẽ là chuyển một con chip màu đen trong cọc A và một con chip trắng - thành đống B. Nhưng làm cách nào?
cleverMove :: Game -> Game
cleverMove game = game & pileA . blacks -~ 1
& pileA . whites +~ 1
& pileB . blacks +~ 1
& pileB . whites -~ 1
Không phải rất thanh lịch. Làm thế nào tôi có thể làm điều đó mà không cần tham khảo mỗi đống hai lần?
Điều duy nhất tôi đã đưa ra (và tôi không thích nó):
cleverMove game = game & pileA %~ (blacks -~ 1)
. (whites +~ 1)
& pileB %~ (blacks +~ 1)
. (whites -~ 1)
(Xin lỗi trước nếu nó rõ ràng - Tôi kinda mới để ống kính và tôi cảm thấy mất trên biển của combinators và khai thác lens
cung cấp. có lẽ tất cả mọi thứ cho nhu cầu của mọi người trốn ở đó. Không phải là nó xấu, tất nhiên! nhưng tôi muốn có cũng bao gồm một hướng dẫn đầy đủ.)
Bạn không thích điều gì về tùy chọn 2? Nó không thể súc tích hơn thế, đúng không? – leftaroundabout
@leftaroundabout Tôi không thích rằng tôi đã phải sử dụng dấu ngoặc đơn, trở nên vụng về khi có nhiều biểu thức liên quan đến nhau - chẳng hạn như 'do' khối và các cấp độ lồng nhau khác. – Artyom
Tôi nghĩ rằng nó sẽ giúp ích nếu bạn cho thấy một số mã giả thô tương ứng với cú pháp lý tưởng của bạn. –