在这种情况下,scala的类型检查如何工作?

编程入门 行业动态 更新时间:2024-10-28 14:28:46
本文介绍了在这种情况下,scala的类型检查如何工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 // Start writing your ScalaFiddle code here sealed trait DSL[A]{ // def run(): A ={ // this match { // case GetLength(something) => // something.length // case ShowResult(number) => // s"the length is $number" // } // } } case class GetLength(something: String) extends DSL[Int] case class ShowResult(number: Int) extends DSL[String] def run[A](fa:DSL[A]): A ={ fa match { case GetLength(something) => something.length case ShowResult(number) => s"the length is $number" } } val dslGetLength = GetLength("123456789") val length = run(dslGetLength) val dslShowResult = ShowResult(length) println(run(dslShowResult)) // print: the length is 9

在此处scalafiddle

  • 为什么 run 函数不能在 DSL [A] 特性中编译,但可以在外部工作?
  • 在这种情况下,类型推断如何工作?
  • why does the run function not compile in the DSL[A] trait, but worked outside?
  • how does type inference work in this case?
推荐答案

这是广义抽象数据类型的情况.

This is a case of generalized abstract data type.

当您有 DSL [A] 且函数返回 A 时,编译器可以证明:

When you have a DSL[A] and function returning A, compiler can prove that:

  • 用于 case GetLength A = Int ,因此您可以在那里返回 Int
  • 用于 case ShowResult A = String ,因此您可以返回 String
  • for case GetLength A=Int so you can return Int there
  • for case ShowResult A=String so you can return String

但是,众所周知,Scala 2没有对GADT的完美支持,因此有时编译器即使可以工作也会失败.我猜有些编译器开发人员可以弄清楚确切的情况,但是有趣的是,它可以解决:

however, Scala 2 is known to not have a perfect support of GADTs, so sometimes compiler fails, even if it should work. I guess some compiler dev could figure out the exact case, but, interestingly, it can be worked around with:

sealed trait DSL[A]{ def run(): A = DSL.run(this) } object DSL { def run[A](fa:DSL[A]): A ={ fa match { case GetLength(something) => something.length case ShowResult(number) => s"the length is $number" } } } case class GetLength(something: String) extends DSL[Int] case class ShowResult(number: Int) extends DSL[String]

我的疯狂猜测是,通用方法中的模式匹配在编译器中是一种特殊情况,当 A 固定时不会触发.我认为是这样,因为以下代码也可以工作:

My wild guess would be that pattern matching in a generic method is kind of a special case in a compiler, which is not triggered when A is fixed. I think that, because the following code also works:

sealed trait DSL[A]{ def run(): A = runMe(this) private def runMe[B](dsl: DSL[B]): B = { dsl match { case GetLength(something) => something.length case ShowResult(number) => s"the length is $number" } } }

这同样会失败:

sealed trait DSL[A]{ def run(): A = { val fa: DSL[A] = this // make sure error is not related to special treatment of "this", this.type, etc fa match { case GetLength(something) => something.length case ShowResult(number) => s"the length is $number" } } }

cmd4.sc:5: constructor cannot be instantiated to expected type; found : ammonite.$sess.cmd4.GetLength required: ammonite.$sess.cmd4.DSL[A] case GetLength(something) => ^ cmd4.sc:7: constructor cannot be instantiated to expected type; found : ammonite.$sess.cmd4.ShowResult required: ammonite.$sess.cmd4.DSL[A] case ShowResult(number) => ^ Compilation Failed

换句话说,我怀疑类型参数会改变事物的评估方式:

In other words, I suspect that type parameter change how things are being evaluated:

  • def runMe [B](dsl:DSL [B]):B 具有类型参数,因此 match 与 B 进行比较,在每种情况下,可以证明 B 的值是某种特定类型(Int,String)
  • 在 def run:A 中,但是以某种方式阻止了编译器进行这种分析-恕我直言,这是一个bug,但这也许是某些晦涩功能的结果.
  • def runMe[B](dsl: DSL[B]): B has a type parameter, so results of each case inside match are compared against B where for each case value of B can be proven to be some specific type (Int, String)
  • in def run: A however compiler is somehow prevented from making such analysis - IMHO it is a bug, but perhaps it is a result of some obscure feature.

从我看到的相同错误中发现了Dotty,所以它要么是重复的错误,要么是类型级别检查器的限制(毕竟,所有GADT尚未广泛使用din Scala)-我建议将问题报告给Scala/Dotty团队让他们决定是什么.

From what I see the same error occurs in Dotty, so it is either duplicated bug or a limitation of a type-level checker (after all GADT aren't widely use din Scala, yet) - I would suggest reporting issue to Scala/Dotty team and letting them decide what it is.

更多推荐

在这种情况下,scala的类型检查如何工作?

本文发布于:2023-08-04 02:25:30,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1292029.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:在这种情况下   类型   工作   scala

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!