问题描述
我正在尝试跟踪构造序列(大量 println)并拥有此代码 https://scastie.scala-lang.org/4DRXuhUZS8mN551eI7vN3Q
<item name="primaryTextColorDefault">
当我运行它时,它会打印出来
import shapeless._
object abc {
sealed trait List[+T]
case class Cons[T](hd: T,tl: List[T]) extends List[T]
sealed trait Nil extends List[nothing]
case object Nil extends Nil
trait Show[T] {
def apply(t: T): String
}
object Show {
// Base case for Int
implicit def showInt: Show[Int] = new Show[Int] {
println("222")
def apply(t: Int) = t.toString
println("222 end")
}
// Base case for Nil
implicit def showNil: Show[Nil] = new Show[Nil] {
def apply(t: Nil) = "Nil"
}
// without Lazy,resoving sc requires resolving sl,which in turn sc -- infinite looping
// Lazy stops this looping and saying I got this,so go on to resolve showCons using proxy st and sl. real st and sl can be accessed using st.value and sl.value
// which will lazily resolved.
// Case for Cons[T]: note (mutually) recursive implicit argument referencing Show[List[T]]
implicit def showCons[T](implicit st: Lazy[Show[T]],sl: Lazy[Show[List[T]]]): Show[Cons[T]] = {
val t = new Show[Cons[T]] {
println(" 111")
def apply(t: Cons[T]) = {
println(" apply 111 ")
println(s" try to show ${t.tl}")
val sss = s"Cons(${show(t.hd)(st.value)},${show(t.tl)(sl.value)})"
println(" apply 111 end ")
sss
}
println(" 111 end") // the reason 111 comes before 333 at the beginning is determined by internal algorithm of Lazy
}
t
}
// Case for List[T]: note (mutually) recursive implicit argument referencing Show[Cons[T]]
implicit def showList[T](implicit sc: Lazy[Show[Cons[T]]]): Show[List[T]] = new Show[List[T]] {
println(" 333")
def apply(t: List[T]) = t match {
case n: Nil => show(n)
case c: Cons[T] => {
println(" apply 333")
val tmp = show(c)(sc.value) //explicitly passing down parameter
println(" apply 333 end")
tmp
}
}
println(" 333 end")
}
}
def show[T](t: T)(implicit s: Show[T]) = s(t)
def main(args: Array[String]): Unit = {
val l: List[Int] = Cons(1,Cons(2,Cons(3,Nil)))
println(show(l))
}
}
为什么 111
111 end
333
333 end
apply 333
apply 111
try to show Cons(2,Nil))
222
222 end
333
333 end
apply 333
apply 111
try to show Cons(3,Nil)
apply 333
apply 111
try to show Nil
apply 111 end
apply 333 end
apply 111 end
apply 333 end
apply 111 end
apply 333 end
Cons(1,Nil)))
和 111
在 111 end
和 333
之前被执行(构造),即使 333 end
中包含 implicit sc: Lazy[Show[Cons[T]]]
?不应该延迟到 Lazy
被引用吗?
我可以看到 sc.value
和 st
是惰性构造的,但是想知道为什么 sl
是立即构造的? Lazy 算法是否认为构造 sc
不会导致无限循环问题?
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)