problem with sum type and focus
mtumilowicz opened this issue · comments
libs
I am using newest monocle
"dev.optics" %% "monocle-core" % "3.1.0",
"dev.optics" %% "monocle-macro" % "3.1.0",
with single import
import monocle.syntax.all._
and scala 2.13.10
problem
I would like to change email when PaymentMethod
is PayPal
(equivalent of copy)
val modified = user.copy(paymentMethod = user.paymentMethod match {
case PayPal(_) => PayPal(newEmail)
case dc@DebitCard(_,_,_) => dc
})
with quicklens I do simply
user.modify(_.paymentMethod.when[PayPal].email).setTo(newEmail)
and everything works, I would like to have something similar with monocle
code
case class User(name: String, paymentMethod: PaymentMethod)
sealed trait PaymentMethod
object PaymentMethod {
case class PayPal(email: String) extends PaymentMethod
case class DebitCard(
cardNumber: String,
expirationDate: YearMonth,
securityCode: Int
) extends PaymentMethod
}
first try:
user.focus(_.paymentMethod.as[PayPal].email).replace(newEmail)
compilation error
value as is not a member of shared.user.PaymentMethod
another try:
user.focus(_.paymentMethod.focus().as[PayPal].email).replace(newEmail)
I get compilation error
value email is not a member of monocle.AppliedPrism[shared.user.PaymentMethod,shared.user.PaymentMethod.PayPal]
when I do something like this
val result: PaymentMethod = user
.focus(_.paymentMethod.focus().as[PayPal].modify(_.focus(_.email).replace(newEmail)))
.get
I get PaymentMethod
as a return instead of User
however when I create everything by myself I get what I need
val newEmail = "newemail@gmail.com"
val setPaymentMethod = GenLens[User](_.paymentMethod)
val setPayPalEmail = Prism.partial[PaymentMethod, String]{case PayPal(x) => x}(PayPal)
val updatePayPalEmail = setPaymentMethod andThen setPayPalEmail
val result: User = updatePayPalEmail.replace(newEmail)(user)
how to do the same with focus
?
@machisuji you would need to be using scala 3 to generate this optic.
Focus
in scala 2 is much more limited. You can only using to generate lenses for fields inside a case class.