英文:
Aux pattern not working for nested implicits
问题
以下是翻译好的代码部分:
sealed trait Types
object Types {
case class A(value: Int) extends Types
case class B(value: String, flag: Boolean) extends Types
case class L(value: Types, n: Int) extends Types
}
trait Generate[In] {
type Out
def generate(in: In): Out
}
object Generate {
type Aux[I, O] = Generate[I] {type Out = O}
implicit object AGenerate extends Generate[Types.A] {
override type Out = Int
override def generate(a: Types.A): Out = a.value
}
implicit object BGenerate extends Generate[Types.B] {
override type Out = String
override def generate(b: Types.B): Out = if (b.flag) b.value else "nope"
}
implicit def lGenerate[T, O](implicit aux: Aux[T, O]): Generate[Types.L] = new Generate[Types.L] {
override type Out = List[O]
override def generate(in: Types.L): Out = List.fill(in.n)(aux.generate(in.value))
}
implicit class RichGenerator[I](in: I) {
def generate[O](implicit aux: Aux[I, O]): O = aux.generate(in)
}
}
object Test extends App {
import Types._
import Generate._
val a = A(1)
val b = B("yep", flag = true)
println(a.generate) // 打印 1: Int
println(b.generate) // 打印 "yep": String
println(L(a, 3).generate) // 打印 List(1, 1, 1)
println(L(b, 2).generate) // 打印 List("yep", "yep")
println(L(L(a, 3), 2).generate) // 打印 List(List(1, 1, 1), List(1, 1, 1))
}
请注意,我已经将 "
替换为实际的引号字符。如果你有其他问题,请随时提出。
英文:
I have the following Types
sealed trait Types
object Types {
case class A(value: Int) extends Types
case class B(value: String, flag: Boolean) extends Types
case class L(value: Types, n: Int) extends Types
}
I want to have a generate
method that will generate an output based on the input type, and the output might have different types. I tried to use the Aux pattern and for type A
and type B
the values are generated.
trait Generate[In] {
type Out
def generate(in: In): Out
}
object Generate {
type Aux[I, O] = Generate[I] {type Out = O}
implicit object AGenerate extends Generate[Types.A] {
override type Out = Int
override def generate(a: Types.A): Out = a.value
}
implicit object BGenerate extends Generate[Types.B] {
override type Out = String
override def generate(b: Types.B): Out = if (b.flag) b.value else "nope"
}
// implicit def lGenerate[T, O](implicit aux: Aux[T, O]): Generate[Types.L] = new Generate[Types.L] {
// override type Out = List[O]
//
// override def generate(in: Types.L): Out = List.fill(in.n)(aux.generate(in.value))
// }
implicit class RichGenerator[I](in: I) {
def generate[O](implicit aux: Aux[I, O]): O = aux.generate(in)
}
}
object Test extends App {
import Types._
import Generate._
val a = A(1)
val b = B("yep", flag = true)
println(a.generate) // prints 1: Int
println(b.generate) // prints "yep": String
}
However, when I try to generate a value for type L
, which depends on Types
, then the implicit resolution fails.
My goal is to obtain the following outputs:
println(L(a, 3).generate) \\ prints List(1,1,1)
println(L(b, 2).generate) \\ prints List("yep", "yep")
println(L(L(a,3), 2).generate) \\ prints List(List(1,1,1), List(1,1,1))
答案1
得分: 2
你可能想要正确地将 Aux
类型链接在一起。
首先,让我们将 L
做成泛型:
final case class L[T <: Types](value: T, n: Int) extends Types
然后,让我们正确定义它的 Generator
实例:
implicit def lGenerate[T <: Types, O](implicit aux: Aux[T, O]): Aux[Types.L[T], List[O]] =
new Generate[Types.L[T]] {
override type Out = List[O]
override def generate(in: Types.L[T]): Out =
List.fill(in.n)(aux.generate(in.value))
}
你可以在 这里 看到代码运行的效果。
英文:
You probably want to properly link the Aux
types together.
First, let's make L
generic:
final case class L[T <: Types](value: T, n: Int) extends Types
Then, let's properly define its Generator
instance:
implicit def lGenerate[T <: Types, O](implicit aux: Aux[T, O]): Aux[Types.L[T], List[O]] =
new Generate[Types.L[T]] {
override type Out = List[O]
override def generate(in: Types.L[T]): Out =
List.fill(in.n)(aux.generate(in.value))
}
You can see the code running here.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论