现在,我想出了这个:
case class Chicken[T](h: Holder[T, _]) {
def get = h.chicken
override def toString = get.toString
}
case class Egg[U](h: Holder[_, U]) {
def get = h.egg
override def toString = get.toString
}
implicit def egg[T] = (_: Egg[T]).get
implicit def chicken[T] = (_: Chicken[T]).get
case class Holder[U, T] (chickenF: (Egg[T], Chicken[U]) => (U, T)) {
val (chicken, egg) = chickenF( Egg(this), Chicken(this))
}
def mutual[U, T](chickenF: (Egg[T], Chicken[U]) => (U, T)) = {
val h = new Holder(chickenF)
h.chicken -> h.egg
}
trait Named { //to avoid unfinite toString
def name: String
override def toString = name
}
用法:
case class A(name: String, b: Egg[B])
case class B(name: String, a: Chicken[A]) extends Named
val (a, b) = mutual[A, B](A("a", _) -> B("b", _))
val (a2, b2) = mutual[A, B]{ (b2, a2) => //alternative for complex cases
A("a", b2) -> B("b", a2)
}
println(a)
println(b)
println(a.b)
println(b.a)
结果:
A(a,b)
b
b
A(a,b)
仍然希望有一个库来解决这个问题,比如 scalaz 或基于某些宏的解决方案。