使用无形状类型不等式时如何自定义 Scala 模糊隐式错误 [英] How can I customize Scala ambiguous implicit errors when using shapeless type inequalities

查看:36
本文介绍了使用无形状类型不等式时如何自定义 Scala 模糊隐式错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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"

I dont think that error message "ambiguous implicit found" is friendly, how can I customize it to say something like "the sum of 2 NAT value should not equal to 7"

非常感谢

推荐答案

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

shapeless's =:!= (and similar type inequality operators) inherently exploit ambiguous implicits to encode Prolog-style negation as failure. And, as you've observed, Scala doesn't have a mechanism which allows library authors to provide more meaningful error messages when ambiguity is expected. Perhaps it should, or perhaps Scala should provide a more direct representation of the negation of a type making this encoding unnecessary.

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

Given that you've couched the question in terms of Nats I think it's probably reasonable that you're trying to work with type inequality. If it weren't Nats my recommendation in answer to another question that a type class directly encoding the relation of interest would apply here too. As it is though, I recommend that same solution as a workaround for not being able to provide better error messages.

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)
                         ^

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

The technique (hiding an expected ambiguous implicit behind an implicit we expect to be not found in the case of underlying ambiguity) is generally applicable, but is obviously fairly heavyweight ... another reason why type inequalities should be avoided if at all possible.

这篇关于使用无形状类型不等式时如何自定义 Scala 模糊隐式错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆