scala - 有没有办法对类型进行递归隐式定义?

标签 scala

我正在尝试打印皮亚诺数字,如下所示:

sealed trait Nat
trait _0 extends Nat
trait Succ[N <: Nat] extends Nat

type _1 = Succ[_0]
type _2 = Succ[_1]

class RepNat[T <: Nat](val value: Int)
def rep[T <: Nat](implicit r: RepNat[T]) = r.value
implicit val repZero = new RepNat[_0](0)
implicit def repSucc[A <: Succ[B], B <: Nat](implicit r: RepNat[B]): RepNat[A] = new RepNat[A](r.value + 1)
println(rep[_0])
println(rep[_1])
// does not work, implicits do not resolve recursively:
// implicitly[RepNat[_2]]
// println(rep[_2])

// but explicit instantiation works:
println(rep[_2](repSucc(implicitly[RepNat[_1]])))

最佳答案

递归隐式确实有效。以下定义适用于 _2 :

implicit def repSucc[A <: Nat, B <: Nat](implicit 
  ev: A <:< Succ[B], 
  r: RepNat[B]
): RepNat[A] = 
  new RepNat[A](r.value + 1)

我认为原因是 repSucc获取单个实际类型参数 A ,需要计算B从那。根据您的定义,它会尝试分配 AB同时,因此B被有效分配给Nothing

这是 Scala 中类型推断的常见问题,通常的解决方案是移动类型绑定(bind) A <: M[B]到广义类型约束A <:< M[B]

另外,请注意隐式参数的顺序很重要:编译器首先计算 B来自Aev: A <:< Succ[B] ,然后找到 RepNat实现B ,可能是递归的。

关于scala - 有没有办法对类型进行递归隐式定义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40690370/

相关文章:

scala - 将数据框中的向量列转换回数组列

scala - 在 scala 中读取 csv 的通用类

scala - 如何从 Scala 中的 json 格式的表单中获取数组?

scala - 从数据模型创建数据表时出现 NullPointerException

scala - 在 Apache Spark 中,如何按两个共享值对 RDD 的所有行进行分组?

java - 在 Jetty 应用程序中部署时,Stanford CoreNLP 找不到正确版本的 ejml

scala - 如何修复 NoSuchMethodError?

scala - 如何从actor内部获取actor系统引用

scala - 为什么cats在评估Reader时返回 `Id[T]`?

scala - Source.fromFile 不适用于 HDFS 文件路径