scala - 使用无形状类型不等式时如何自定义 Scala 模糊隐式错误

标签 scala shapeless

def typeSafeSum[T <: Nat, W <: Nat, R <: Nat](x: T, y: W)
         (implicit sum: Sum.Aux[T, W, R], error: R =:!= _7) = x

typeSafeSum(_3, _4) //compilation error, ambiguous implicit found.

我不认为错误消息“模糊的隐式发现”是友好的,我如何自定义它以说“2 NAT 值的总和不应等于 7”

提前谢谢了

最佳答案

无形的=:!= (以及类似类型的不等式运算符)固有地利用模糊的隐式将 Prolog 样式的否定编码为失败。而且,正如您所观察到的,Scala 没有允许库作者在预期歧义时提供更有意义的错误消息的机制。也许它应该,或者 Scala 应该提供一种更直接的否定类型的表示,使这种编码变得不必要。

鉴于您已经根据 Nats 提出了问题我认为您尝试处理类型不等式可能是合理的。如果不是 Nats我在 answer to another question 中的推荐直接编码感兴趣的关系的类型类也适用于此。尽管如此,我建议使用相同的解决方案作为无法提供更好的错误消息的解决方法。

import shapeless._, nat._, ops.nat._

@annotation.implicitNotFound(msg = "${A} + ${B} = ${N}")
trait SumNotN[A <: Nat, B <: Nat, N <: Nat]
object SumNotN {
  implicit def sumNotN[A <: Nat, B <: Nat, R <: Nat, N <: Nat]
    (implicit sum: Sum.Aux[A, B, R], error: R =:!= N): SumNotN[A, B, N] =
      new SumNotN[A, B, N] {}     
}

def typeSafeSum[T <: Nat, W <: Nat](x: T, y: W)
  (implicit valid: SumNotN[T, W, _7]) = x

scala> typeSafeSum(_3, _4)
<console>:20: error: shapeless.nat._3 + shapeless.nat._4 = shapeless.nat._7
              typeSafeSum(_3, _4)
                         ^

该技术(将预期的模糊隐含隐藏在我们期望在潜在歧义的情况下找不到的隐含之后)通常适用,但显然是相当重量级的......如果可能的话,应该避免类型不等式的另一个原因。

关于scala - 使用无形状类型不等式时如何自定义 Scala 模糊隐式错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25006443/

相关文章:

scala - KafkaUtils API |偏移量管理 | Spark 流

scala - 如何将选项转换为无?

scala - 更改多个 Spark DataFrame 列类型,动态且可配置

Scala.Either getOrElse 方法

scala - 变换/遍历 Shapeless 的 HMap

Scala 类型类,用于获取类型成员的最具体类型

scala - Spark 无法与 pureconfig 一起使用

scala - 获取字段键作为副产品

scala - scala如何对待伴生对象?

scala - 我们可以通过参数调用scala函数多态而不是无形吗