Как "изменить" отдельные значения в больших объектах элегантным способом?
Например, у меня есть
data ShipDesign = ShipDesign {
offense :: Offense
, defense :: Defense
, maxHealth :: Integer
, repairRate :: Integer
, stealth :: Integer
, radar :: Integer
, speed :: Integer
, shipType :: String
...
}
Теперь я хочу изменить защиту.
Известный способ сделать это:
changeDefense :: (Defense -> Defense) -> ShipDesign -> ShipDesign
changeDefense fDef [email protected](ShipDesign o d m rr s r sp st ...) = ShipDesign o (fDef d) m rr s r sp st ...
который не является элегантным. Особенно в играх его общий для изменения всего нескольких значений за шаг.
Мой вопрос: есть ли библиотека, шаблон дизайна или другой способ изменить одно значение более элегантным образом?
Ответы
Ответ 1
Да, вы можете использовать нотацию записи записи:
changeDefense :: (Defense -> Defense) -> ShipDesign -> ShipDesign
changeDefense fDef sd = sd { defense = fDef (defense sd) }
По мере того как вы будете работать с ним, ограничения нот записи обновления покажутся сами собой, и вы захотите что-то более мощное. В этот момент вы должны начать изучать lenses.
Ответ 2
Интересно, почему никто не предлагал линзы?
Я рекомендую это краткое введение Габриэля Гонсалеса:
http://www.haskellforall.com/2013/05/program-imperatively-using-haskell.html?m=1
Изменить: о... Я прочитал последнее предложение. Но предложение все еще стоит.