Home > database >  Modify sequence at index using Monocle
Modify sequence at index using Monocle

Time:09-01

I can modify Map using focus and index just fine. Is there a similar functionality in Monocle to update a sequence at given index?

import monocle.syntax.all._

case class C(member: Int)

val map = Map(0 -> C(0), 1 -> C(1))
case class MapContainer(seq: Map[Int, C])
val containedMap = MapContainer(map)
containedMap.focus(_.seq).index(0).replace(C(10)) // works fine

val seq = IndexedSeq(C(0), C(1), C(2))
case class Container(seq: IndexedSeq[C])
val containedSeq = Container(seq)

containedSeq.focus(_.seq).index(0).replace(C(10)) // does not compile

The error is Could not find an instance of Index[IndexedSeq[C],Int,A1].

Is such functionality available for Monocle? I was using Quicklens previously and it used at for both maps and sequences. Unfortunately Quicklens Scala 3 support is not very good at this point, therefore I am exploring alternatives.

CodePudding user response:

From what I see .index relies on Index instance which should be available for the type that you want to apply index to.

If you modify your code to this:

val seq = IndexedSeq(C(0), C(1), C(2))
case class Container(seq: List[C]) // List instead of IndexedSeq
val containedSeq = Container(seq.toList)

containedSeq.focus(_.seq).index(0).replace(C(10))

it does compile.

So the issue is lack of instance for IndexedSeq. Among the build-in instances for standard data types you can see:

  implicit def seqIndex[A, S[B] <: SeqOps[B, S, S[B]]]: Index[S[A], Int, A] // this should work
  implicit def listIndex[A]: Index[List[A], Int, A]
  implicit def lazyListIndex[A]: Index[LazyList[A], Int, A]
  implicit def listMapIndex[K, V]: Index[ListMap[K, V], K, V]
  implicit def mapIndex[K, V]: Index[Map[K, V], K, V]
  implicit def sortedMapIndex[K, V]: Index[SortedMap[K, V], K, V]
  implicit val stringIndex: Index[String, Int, Char]
  implicit def vectorIndex[A]: Index[Vector[A], Int, A]

but from what I see seqIndex was added 2 months ago and not released yet (3.1.0 was released a year ago).

So your best bet is to use some specific data structure or implement this implicit yourself.

  • Related