Modifying an attribute with Monocle Lenses using the value of another attribute
Asked Answered
P

1

7

I have the following model

import monocle.macros.Lenses
import monocle.function.all._
import monocle.std.list._

@Lenses("_") case class Poll(pollChoices: List[PollChoice], totalVoteCount: Int)
@Lenses("_") case class PollChoice(id: Int, value: Int, percentage: Int)

What I'm trying to achieve is to update the pollChoices attribute of the Poll by updating all the percentage attributes of each element in the pollChoices List. My problem is that the new percentage values are based on the value attribute of the PollChoice and the totalValueCount of the Poll.

What I did so far is:

val poll = Poll(List(PollChoice(1,3,0), PollChoice(2,5,0)), 8)

(Poll._pollChoices composeTraversal each composeLens PollChoice._percentage)
  .modify(oldPercentage => oldPercentage + 1)(poll)

But this way i can only access the percentage attribute of the element I'm updating in the modify step, I also need the value.

I'm assuming I would need to use Traversable to do this kind of modification, but am not sure how. Thanks.

Pulchia answered 13/12, 2016 at 14:23 Comment(0)
H
3

I don't think that you can express this in a single lens, but a separate lens inside .modify works well:

Poll._pollChoices.composeTraversal(each).modify { choice =>
  PollChoice._percentage.set(choice.value / poll.totalVoteCount)(choice)
}(poll)
Handknit answered 16/12, 2016 at 13:25 Comment(1)
Thanks, thats fine for my use case!Pulchia

© 2022 - 2024 — McMap. All rights reserved.