为什么 Scala 3 中没有身份转换?

Why is there no identity Conversion in Scala 3?

提问人:steinybot 提问时间:10/12/2023 更新时间:10/12/2023 访问量:43

问:

Scala 不支持隐式转换链接(有充分的理由)。在设计一个 API 时,有一些不幸的情况,它提供了隐式转换,你需要它来链接。

使用 Scala 2 隐式,这很容易解决,因为它允许有另一个隐式转换作为参数。例如:

  implicit def fromUndefOr[A, Result](j: UndefOr[A])(implicit conv: A => TypedReactElement[Result]): TypedReactElement[Result] =
    j.fold(null.asInstanceOf[TypedReactElement[Result]])(conv)

在 Scala 3 中,这可能如下所示:

  given fromOption[A, Result](using conv: Conversion[A, TypedReactElement[Result]]): Conversion[Option[A], TypedReactElement[Result]] =
    _.fold(null.asInstanceOf[TypedReactElement[Result]])(conv)

然而,使用 Scala 3 有一个主要的缺点。没有身份转换。这意味着微不足道的情况将失败:Conversion

def mayConvert[A, B](using conv: Conversion[A, B])(a: A): B =
  conv(a)

val noConversion: Int = mayConvert(123)
// No given instance of type Conversion[A, B] was found for parameter conv of method mayConvert in object Playground

这很烦人,也是坚持使用 s 的另一个原因。implicit def

这有什么好的理由吗?

隐式转换 Scala-3

评论

3赞 Mateusz Kubuszok 10/12/2023
TBH,我认为您使用转换错误。唯一应该做的两件事是启用类似的事情,并且不要混淆(以避免发生像成为 conv) 这样的事故。它不应该是派生的,它应该专门为作者知道它是安全的特定类型提供的。如果要执行派生...我建议创建一个专用的类型类,因为您希望使人们所依赖的 OOTB 事物成为可能。val a: A; def f(b: B); f(a) /* convert A to B*/Function[A, B]implicit List[String]]Int => String
1赞 Daenyth 10/13/2023
是的,这看起来您真正想要的是拥有某种解析类型类,例如 JSON 。 不是为了这个,像这样使用它是极其不利于用户的 API 设计Decoder[A]Conversion
0赞 steinybot 11/2/2023
我正在用于你所描述的情况。 是捕获某些类型信息的新类型。我知道从转换到可以安全转换。这部分完全没问题。我可以打电话给一个,只要有转换。希望你同意那里没有什么奇怪的。我也应该可以打电话。我可以用 typeclass 做同样的事情,然后有一个 if a exists 或只使用 defs。TypedReactElement[Result]ATypedReactElement[Result]def f(a: TypedReactElement[Result])Adef f(a: js.UndefOr[TypedReactElement[Result]])AConverterConversionConverter
0赞 steinybot 11/2/2023
这甚至不像是我自己想出的。这是 Slinky 版本: ' @inline implicit def jsUndefOrToElement[E](j: js.UndefOr[E])(隐式 cv: E => ReactElement): ReactElement = { val x = if (j.isDefined) cv(j.get) else null.asInstanceOf[ReactElement] x }'

答: 暂无答案