David
05/22/2024, 11:11 AM@optics data class Person(val name: String, val age: Int, val friends: List<Person>) {
companion object
}
Person.friends.every(Every.list()).age.modify(this) { it + 1 }
How can i add a filter on some property, say name starts with x
and then modify age with the lens that focus those elements that fulfil the predicate?dave08
05/22/2024, 11:14 AMdave08
05/22/2024, 11:15 AMif (...) ... else it
inside the modifyDavid
05/22/2024, 11:16 AMage
so I won't have the other properties of the item I'm looking at right?dave08
05/22/2024, 11:16 AMDavid
05/22/2024, 11:18 AMI think you can make your own Every.list() that takes a lambda...?Tried to find this but couldn't 😞 I know I've seen a sample of filtering based on
index
but not properties 😞dave08
05/22/2024, 11:18 AMpublic fun <A> list(): Every<List<A>, A> =
object : Every<List<A>, A> {
override fun modify(source: List<A>, map: (focus: A) -> A): List<A> =
source.map(map)
override fun <R> foldMap(M: Monoid<R>, source: List<A>, map: (focus: A) -> R): R =
source.foldMap(M, map)
}
I think you could add a parameter there that could take a filter and use filter before map or foldMap...?dave08
05/22/2024, 11:20 AMDavid
05/22/2024, 11:22 AMdave08
05/22/2024, 11:27 AMimport arrow.core.foldMap
import arrow.optics.Every
import arrow.typeclasses.Monoid
val list = listOf("one", "two", "two", "three")
fun <A> listFiltered(block: (A) -> Boolean) = object : Every<List<A>, A> {
override fun modify(source: List<A>, map: (focus: A) -> A): List<A> =
source.filter(block).map(map)
override fun <R> foldMap(M: Monoid<R>, source: List<A>, map: (focus: A) -> R): R =
source.filter(block).foldMap(M, map)
}
println(listFiltered<String> { it == "two" }.modify(list) { "three" })
dave08
05/22/2024, 11:30 AMdave08
05/22/2024, 11:34 AMfun <A> listFiltered(block: (A) -> Boolean) = object : Every<List<A>, A> {
override fun modify(source: List<A>, map: (focus: A) -> A): List<A> =
source.map { if (block(it)) map(it) else it }
override fun <R> foldMap(M: Monoid<R>, source: List<A>, map: (focus: A) -> R): R =
source.filter(block).foldMap(M, map)
}
dave08
05/22/2024, 11:34 AMdave08
05/22/2024, 11:35 AMdave08
05/22/2024, 11:35 AMdave08
05/22/2024, 12:36 PMPerson.friends.every(listFiltered { it.name ==... }).age.modify(this) { it + 1 }
Alejandro Serrano.Mena
05/22/2024, 12:41 PMdave08
05/22/2024, 12:42 PMsince it doesn’t allow you to set values backWhat do you mean?
dave08
05/22/2024, 12:44 PMdave08
05/22/2024, 12:44 PMdave08
05/22/2024, 12:45 PMAlejandro Serrano.Mena
05/22/2024, 12:46 PMAlejandro Serrano.Mena
05/22/2024, 12:48 PMdave08
05/22/2024, 12:48 PMAlejandro Serrano.Mena
05/22/2024, 1:12 PMDavid
05/22/2024, 1:25 PM