Search code examples
scalashapeless

Defining a shapeless replacer


I wonder how can I fix this Scala code using the Shapeless library so that it compiles:

object boo {

  import shapeless._

  sealed trait Bibby
  case class LittleBibby(i: Int) extends Bibby
  case class BigBibby(s: String) extends Bibby
  type Bibbies = LittleBibby :: BigBibby :: HNil

  val defaultBibbies: Bibbies = LittleBibby(1) :: BigBibby("beep") :: HNil

  def update(b: Bibby, bibbies: Bibbies) : Bibbies = bibbies.updatedElem(b)

  val demo: Bibbies = update(LittleBibby(3), defaultBibbies)

}

I get the following error message:

could not find implicit value for parameter replacer:shapeless.Replacer[boo.Bibbies,boo.Bibby,boo.Bibby]
def update(b: Bibby, bibbies: Bibbies) : Bibbies = bibbies.updatedElem(b)

I have tried to look through the shapeless source code in order to find a solution to create the missing implicit Replacer, but to no avail :/


Solution

  • For shapeless.Replacer information about actual element type should be available in compile time. There is no element of type Bibby in Bibbies, so there is nothing to replace.

    You should use a generic type for b, and also you should add required Replacer[Bibbies, B, B] as implicit parameter like this:

    def update[B <: Bibby](b: B, bibbies: Bibbies)(implicit r: Replacer[Bibbies, B, B]) =
      bibbies.updatedElem(b)
    
    update(LittleBibby(3), defaultBibbies)
    // LittleBibby(3) :: BigBibby(beep) :: HNil