Hi Brieuc, congrats for this nice article! As discussed in contributors.scala-lang.org/t/is-f-bound-polymorp… F-bounded polymorphism should most of the time be replaced by a simple minded Typeclass. In your case, this would give the following code (Scala 3 syntax):
trait Info[T, InfoType]:
extension (infoType: InfoType) def update(t: T): InfoType
trait Memory[T]
case class Foo(foo: String)
case class Bar(foo: Foo, foos: List[Foo])
case class FooInfo(fooMemory: Memory[String]):
def update(foo: Foo): FooInfo = ???
object FooInfo:
given Info[Foo, FooInfo] with
extension (fooInfo: FooInfo)
def update(foo: Foo): FooInfo = fooInfo.update(foo)
case class BarInfo(
fooInfo: FooInfo,
foosInfo: ListInfo[Foo, FooInfo]
):
def update(bar: Bar): BarInfo = ???
object BarInfo:
given Info[Bar, BarInfo] with
extension (barInfo: BarInfo)
def update(bar: Bar): BarInfo = barInfo.update(bar)
case class ListInfo[T, InfoType](
infos: List[InfoType]
)(using Info[T, InfoType]):
def update(listInfo: List[T]): ListInfo[T, InfoType] = ???
def updateInfoAtIndex(index: Int, t: T): ListInfo[T, InfoType] =
val updatedInfo = infos(index).update(t)
copy(infos = infos.updated(index, updatedInfo))
Hi Brieuc, congrats for this nice article! As discussed in contributors.scala-lang.org/t/is-f-bound-polymorp… F-bounded polymorphism should most of the time be replaced by a simple minded Typeclass. In your case, this would give the following code (Scala 3 syntax):
trait Info[T, InfoType]: extension (infoType: InfoType) def update(t: T): InfoType
trait Memory[T]
case class Foo(foo: String) case class Bar(foo: Foo, foos: List[Foo])
case class FooInfo(fooMemory: Memory[String]): def update(foo: Foo): FooInfo = ??? object FooInfo: given Info[Foo, FooInfo] with extension (fooInfo: FooInfo) def update(foo: Foo): FooInfo = fooInfo.update(foo)
case class BarInfo( fooInfo: FooInfo, foosInfo: ListInfo[Foo, FooInfo] ): def update(bar: Bar): BarInfo = ???
object BarInfo: given Info[Bar, BarInfo] with extension (barInfo: BarInfo) def update(bar: Bar): BarInfo = barInfo.update(bar)
case class ListInfo[T, InfoType]( infos: List[InfoType] )(using Info[T, InfoType]): def update(listInfo: List[T]): ListInfo[T, InfoType] = ??? def updateInfoAtIndex(index: Int, t: T): ListInfo[T, InfoType] = val updatedInfo = infos(index).update(t) copy(infos = infos.updated(index, updatedInfo))