[英]Why do we need to specify a refined type (or its equivalent Aux) for the output of certain type computations?
在https://jto.github.io/articles/typelevel_quicksort中 :
我们接触到一个Sum
类型,其apply
如下所示:
def apply[A <: Nat, B <: Nat](implicit sum: Sum[A, B]): Aux[A, B, sum.Out] = sum
现在,我们可以直接使用类型细化而不是Aux,但问题仍然存在:为什么这(显式返回类型)是必要的? apply
的返回类型是否具有等于sum的Sum#Out类型,这是不是“显而易见”.Out?
如果我们删除它并且我们只使用val x = Sum[_0, _1]
,它看起来很好,除了添加val y = Sum[x.Out, _1]
将不起作用,说编译器找不到隐式Sum。
为什么编译器似乎“忘记”了x.Out的确切类型?
类型Sum[A, B]
和Sum.Aux[A, B, C] = Sum[A, B] { type Out = C }
是不同的。 后者是前者的亚型。 Sum[A, B]
也是存在类型Sum.Aux[A, B, _]
。
apply
的返回类型是否具有等于sum的Sum#Out类型,这是不是“显而易见”.Out?
没有,
def apply[A <: Nat, B <: Nat](implicit sum: Sum[A, B]) = sum
是相同的
def apply[A <: Nat, B <: Nat](implicit sum: Sum[A, B]): Sum[A, B] = sum
首先,你要定义sum2
:要么是sum1
, sum2
还是简单地归纳
implicit val sum00: Aux[_0, _0, _0] = new Sum[_0, _0] { type Out = _0 }
implicit val sum01: Aux[_0, _1, _1] = new Sum[_0, _1] { type Out = _1 }
implicit val sum10: Aux[_1, _0, _1] = new Sum[_1, _0] { type Out = _1 }
implicit val sum11: Aux[_1, _1, _2] = new Sum[_1, _1] { type Out = _2 }
...
然后当你写
def apply[A <: Nat, B <: Nat](implicit sum: Sum[A, B]): Aux[A, B, sum.Out] = sum
只知道A
和B
足以解决隐式问题。 每个定义的隐含“知道”其特定的C
但如果你只返回Sum[A, B]
这个C
就会被遗忘。
你可以定义
def apply[A <: Nat, B <: Nat, C <: Nat](implicit sum: Aux[A, B, C]): Aux[A, B, C] = sum
但是你必须手动指定C
: Sum[_2, _3, _5]
。
如果我们删除它并且我们只使用
val x = Sum[_0, _1]
,它看起来很好,除了添加val y = Sum[x.Out, _1]
将不起作用,说编译器找不到隐式Sum。
当然。 x.Out
不再是_1
,它只是一些抽象的x.Out
,并且隐含无法解析。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.