Search code examples
scalashapeless

How combine 2 shapeless functions (replaceAt and at) easiest way?


Maybe someone can help me with shapeless? I'm new with it.

My concrete task - create function that convert given tuple element into Option For example:

val inp: (String, Int) = ("zzz", 5)
myfunc(inp, 1)

should returns: ("zzz", Option(5))

I found that I can do these tasks with replaceAt and at functions, but I cant figure out how to do this in one generic function. My best result is this:

def opt[P <: Product, U, V, R](p: P, n: Nat, u: ()=>U)(implicit at: At[P, n.N], replacer: ReplaceAt.Aux[P, n.N, Option[U], (V, R)]):R = {
  val value1: TupleOps[P] = shapeless.syntax.std.tuple.productTupleOps(p)
  val out1 = value1.at(n)
  value1.updatedAt(n, Option(u()))
}

So I can call it like opt(t, 1, ()=> t.at(1)), but I very would like to not use 3rd param

So, in general my issue is:

I cant combine at() output and replaceAt() input.

IDE offer me use At[P, n.N]#Out as at() output but this dont match with U input of replaceAt


Solution

  • Try ModifierAt:

      import shapeless.Nat
      import shapeless.ops.tuple.{At, ModifierAt}
    
      def myfunc[P <: Product, N <: Nat, T, P1 <: Product](p: P, n: N)(implicit
        at: At.Aux[P, N, T],
        modifier: ModifierAt.Aux[P, N, T, Option[T], (T, P1)]): P1 =
        modifier(p, Some(_))._2
    
      myfunc(inp, 1) //("zzz",Some(5))