I'm trying to modify a property on a sealed interface. Are optics for properties of a interface not generated? Can I use some kind of Lens/Prism/Iso to access the property?
@Test
fun `Modify field on sealed interface`() {
val orgA = SealedType.TypeA(0)
// property [value] is not generated by optics, only `SealedType.typeA.value` exists.
val newA = SealedType.value.modify(orgA) { it + 1}
expectThat(newA.value).isEqualTo(1)
}
@optics sealed interface SealedType {
val value: Int
companion object;
@optics data class TypeA(
override val value: Int
) : SealedType {
companion object
}
// TypeB ... same as TypeA
}
Do I have to manually write a Lens like this? Or can it be achieved through Prism/Iso or something else that I've missed?
companion object {
val value: Lens<SealedType, Int> inline get() = Lens(
get = { subject ->
subject.value
},
set = { subject, newValue ->
when (subject) {
is TypeA -> subject.copy(value = newValue)
is TypeB -> subject.copy(value = newValue)
}
}
)
}
This is currently not implemented, but an issue exists for it. https://github.com/arrow-kt/arrow/issues/2829
I'm going to prioritise this higher, because I really would love to have this functionality in Arrow Optics. I am going to try to release this in the coming month.
Thanks for raising here again, I will report back here when it's merged and released in 1.2.2
The current workaround is indeed to write your own optic as you've done here.