在对磁体模式和隐式分辨率顺序here做了一些指示后,我遇到了一个奇怪的问题模式匹配我的磁体类。在第一个例子中,我得到有关非法循环继承的错误,但是通过切换模式匹配我不会:
sealed trait SeqOrFun[T1, T2]
case class SeqMagnet[T](itr: Iterable[T]) extends SeqOrFun[T, T]
case class FunMagnet[T1, T2](f: (T1 => T2)) extends SeqOrFun[T1, T2]
def unfurl[T1, T2](x: SeqOrFun[T1, T2], y: SeqOrFun[T1, T2]): (Iterable[T1], Iterable[T2]) = {
(x, y) match {
case (SeqMagnet(xs: Iterable[T1]), FunMagnet(yf: (T1 => T2))) => (xs, xs.map(yf))
}
}
导致:
<console>:14: error: illegal cyclic inheritance involving unfurl
case (SeqMagnet(xs: Iterable[T1]), FunMagnet(yf: (T1 => T2))) => (xs, xs.map(yf))
^
<console>:14: error: illegal cyclic inheritance involving unfurl
case (SeqMagnet(xs: Iterable[T1]), FunMagnet(yf: (T1 => T2))) => (xs, xs.map(yf))
^
<console>:14: error: illegal cyclic inheritance involving unfurl
case (SeqMagnet(xs: Iterable[T1]), FunMagnet(yf: (T1 => T2))) => (xs, xs.map(yf))
^
<console>:13: error: illegal cyclic inheritance involving unfurl
(x, y) match {
但相反的顺序有效:
sealed trait SeqOrFun[T1, T2]
case class SeqMagnet[T](itr: Iterable[T]) extends SeqOrFun[T, T]
case class FunMagnet[T1, T2](f: (T1 => T2)) extends SeqOrFun[T1, T2]
def unfurl[T1, T2](x: SeqOrFun[T1, T2], y: SeqOrFun[T1, T2]): (Iterable[T1], Iterable[T2]) = {
(x, y) match {
case (FunMagnet(xf: (T2 => T1)), SeqMagnet(ys: Iterable[T2])) => (ys.map(xf), ys)
}
}
编译
<console>:13: warning: match may not be exhaustive.
It would fail on the following input: (FunMagnet(Function1()), FunMagnet(_))
(x, y) match {
^
unfurl: [T1, T2](x: SeqOrFun[T1,T2], y: SeqOrFun[T1,T2])(Iterable[T1], Iterable[T2])
(唯一的变化是
case (SeqMagnet(xs: Iterable[T1]), FunMagnet(yf: (T1 => T2))) => (xs, xs.map(yf))
到
case (FunMagnet(xf: (T2 => T1)), SeqMagnet(ys: Iterable[T2])) => (ys.map(xf), ys)
因为它们是对称的,我不明白如何编译而另一个不能编译。我仍然试图理解错误,因为其他用户似乎从递归类型定义中得到它(我不认为我在这里做)
更新:我相信如果我将磁铁定义为普通类并编写我自己的unapply方法,问题就会消失。