gpt4 book ai didi

scala - 不明确的隐式值是我们想让错误在编译时存在的唯一方法吗

转载 作者:行者123 更新时间:2023-12-04 17:09:37 27 4
gpt4 key购买 nike

trait Foo

trait Bar extends Foo

def doStuff[T <: Foo](x: T)(implicit ev: T =!:= Foo) = x

doStuff(new Foo{}) //ambiguous implicit value
doStuff(new Bar)// successful

隐式解析发生在编译时,所以在这里我认为可能有两个具有完全相同类型的隐式值来触发不明确的东西。

现在我准备把shapeless引入团队,同事们觉得这种含糊的含蓄不理想,我也没有什么强烈的论据。这是为了使 Scala 中的类型安全而这样做的唯一方法吗?如果是,我该怎么做才能自定义错误消息?

编辑:

在无形中,我想让2个NAT的总和不等于7,我可以这样编码使编译失败。
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)

但是错误消息是不明确的隐含值,我该如何自定义错误消息?

最佳答案

在这个(和大多数其他)实例中,一个简单的类型类会比类型不等式测试更好。

想必是想排除的原因FooBar (及其兄弟)有一些属性 Foo缺乏。如果是这种情况,那么您应该创建一个类型类来捕获这些属性,并将其作为 doStuff 的类型参数的要求。 .您可以使用 Scala 的 @implicitNotFound注释以使编译器错误消息在不满足该要求时更易于理解。

@annotation.implicitNotFound(msg = "No Props instance for ${T}")
trait Props[T] {
def wibble(t: T): Double
}

trait Foo
// Note no Props instance for Foo ...

trait Bar extends Foo
object Bar {
// Props instance for Bar
implicit def barProps: Props[Bar] = new Props[Bar] {
def wibble(t: Bar): Double = 23.0
}
}

def doStuff[T <: Foo](t: T)(implicit props: Props[T]) = props.wibble(t)

scala> doStuff(new Foo {})
<console>:11: error: No Props instance for Foo
doStuff(new Foo {})
^

scala> doStuff(new Bar {})
res1: Double = 23.0

如果没有任何此类属性可以区分 Foo来自 Bar那么你应该质疑你的假设,你需要排除 Foo来自 doStuff首先。

如果你在你的项目中使用 shapeless,我会很高兴,但你应该使用 =!:= (和 Scala 自己的 =:= )只是作为最后的手段,如果有的话。

关于scala - 不明确的隐式值是我们想让错误在编译时存在的唯一方法吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24926521/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com