考虑io包装中提供的默认编解码器。
implicitly[io.Codec].name //res0: String = UTF-8
Run Code Online (Sandbox Code Playgroud)
它是“低优先级”隐式的,因此很容易覆盖而不会产生歧义。
implicit val betterCodec: io.Codec = io.Codec("US-ASCII")
implicitly[io.Codec].name //res1: String = US-ASCII
Run Code Online (Sandbox Code Playgroud)
提高优先级也很容易。
import io.Codec.fallbackSystemCodec
implicit val betterCodec: io.Codec = io.Codec("US-ASCII")
implicitly[io.Codec].name //won't compile: ambiguous implicit values
Run Code Online (Sandbox Code Playgroud)
但是我们可以朝相反的方向前进吗?我们可以创建一个低级别的隐式来禁用(“歧义化”)默认值吗?我一直在研究优先级方程式,并使用低优先级隐式变量进行操作,但尚未创建默认值的歧义。
I have a custom class, A, and I have defined some operations within the class as follows:
def +(that: A) = ...
def -(that: A) = ...
def *(that: A) = ...
def +(that: Double) = ...
def -(that: Double) = ...
def *(that: Double) = ...
Run Code Online (Sandbox Code Playgroud)
In order to have something like 2.0 + x make sense when x is of type A, I have defined the following implicit class:
object A {
implicit class Ops (lhs: …Run Code Online (Sandbox Code Playgroud) 我正在尝试编写一个Scala编译器插件,它允许非常通用的代码生成:类似于C预处理器的通用性,但更多类型安全(我不确定这是否是一个糟糕的想法,但它是一个有趣的练习).我理想的用例看起来像这样:
// User code. This represents some function that might take some args
// and outputs an abstract syntax tree.
def createFooTree(...): scala.reflect.runtime.universe.Tree = ...
// Later user code (maybe separate compilation?). Here the user generates
// code programmatically using the function call to |createFooTree| and inserts
// the code using insertTree.
insertTree(createFooTree(...))
Run Code Online (Sandbox Code Playgroud)
重要的插件代码可能如下所示(基于此):
class InsertTreeComponent(val global: Global)
extends PluginComponent
with TypingTransformers {
import global._
import definitions._
override val phaseName = "insertTree"
override val runsRightAfter = Some("parser")
override …Run Code Online (Sandbox Code Playgroud) scala编译器应该为我在下面评论过的if语句生成警告,但事实并非如此.为什么?
sealed trait T
object A extends T
val s:Seq[T] = Seq(A)
val result = s.map {
//This if should produce a compiler warning
case a if(a == "A") =>
"First"
case a =>
//This if should produce a compiler warning
if (a == "A") {
"Second"
}
else
{
"Third"
}
}
Run Code Online (Sandbox Code Playgroud)
其结果将是"第三条:"如你所期望,但是编译器应该产生一个警告就case a if(a == "A")和上if (a == "A"),但很可惜没有警告.
如果我编写以下代码,它的行为就像我期望的那样:
if(A == "A"){
println("can't happen")
}
// warning: comparing values of types A.type and …Run Code Online (Sandbox Code Playgroud) 我正在为refchecks阶段编写一个Scala编译器插件.
如何访问的符号,一个"超级"的呼叫是指,考虑调用点的象征?
例如,在
trait A {
def m() {}
}
trait B extends A {
def m() { super.m() }
}
Run Code Online (Sandbox Code Playgroud)
知道了呼叫站点的符号super.m(),我想获得特征的符号A.
Welcome to Scala 2.12.1 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_121).
Type in expressions for evaluation. Or try :help.
scala> :paste
// Entering paste mode (ctrl-D to finish)
import scala.reflect.runtime._
import scala.reflect.runtime.universe._
import scala.tools.reflect.ToolBox
val mirror = universe.runtimeMirror(universe.getClass.getClassLoader)
val toolbox = mirror.mkToolBox(options = "-Yrangepos")
val text =
"""
|libraryDependencies ++= Seq("org.scala-lang" % "scala-compiler" % "2.10.4") map {
| (dependency) =>{
| dependency
| }
|}
""".stripMargin
val parsed = toolbox.parse(text)
val parsedTrees = parsed match {
case Block(stmt, expr) => …Run Code Online (Sandbox Code Playgroud) 我想定义一个由上限R和更高级类型构造函数参数化的特征,该构造函数F[_]仅接受R. 我希望这个 trait 实现一个多态apply,可以将 anyF[A]转换为Unit,前提是A <: R.
这段代码工作得很好:
import scala.language.higherKinds
// this is the trait with polymorphic `apply`
trait CoCone[R, F[_ <: R]] {
def apply[A <: R](x: F[A]): Unit
}
// Example:
sealed trait Domain
class Dom1 extends Domain
class Fnctr[X <: Domain]
val c = new CoCone[Domain, Fnctr] {
def apply[D <: Domain](x: Fnctr[D]): Unit = ()
}
Run Code Online (Sandbox Code Playgroud)
(见下面关于命名的备注)
现在,如果我通过将R它声明为某个模块的类型成员来抽象它,并Fnctr[A <: …
scala abstract-type higher-kinded-types type-bounds scala-compiler
让我们考虑以下特征:
sealed trait AB
case class A(a: Int) extends AB
case class B(b: Int) extends AB
Run Code Online (Sandbox Code Playgroud)
我试图将collect集合限制为特定的子类.
如果我尝试collect,匹配单个组件并重新组合元组:
scala> Seq.empty[(Int, AB)].collect { case (id, a @ A(_)) => (id, a) } : Seq[(Int, A)]
res6: Seq[(Int, ab.A)] = List()
Run Code Online (Sandbox Code Playgroud)
编译器很高兴,但如果尝试返回完整匹配:
scala> Seq.empty[(Int, AB)].collect { case x @ (_, A(_)) => x } : Seq[(Int, A)]
Run Code Online (Sandbox Code Playgroud)
事情变得丑陋:
<console>:27: error: type mismatch;
found : Seq[(Int, ab.AB)]
required: Seq[(Int, ab.A)]
Seq.empty[(Int, AB)].collect { case x @ (_, A(_)) => …Run Code Online (Sandbox Code Playgroud) scala type-inference pattern-matching scala-collections scala-compiler
我想检查我的代码库以找到“无结果类型测试”警告和“比较无关类型”警告我们的代码库中基本上有一个非常大的错误,如果我们没有忽略这个警告,本可以避免的。我们现在要检查代码以查找我们的代码库中是否还有其他实例?
我正在研究 Scala 中的存在类型2.12.x。为此,我正在测试以下代码:
trait Parent
class ChildA extends Parent
class ChildB extends Parent
def whatIsInside(opt: Option[_ <: Parent]): String = {
opt match {
case _: Option[_ <: ChildA] => "ChildA"
case _: Option[_ <: ChildB] => "ChildB"
case _ => throw new IllegalArgumentException("unknown type")
}
}
whatIsInside(Some(new ChildA))
Run Code Online (Sandbox Code Playgroud)
由于类型擦除,我不希望这在运行时起作用,但是这甚至无法编译。我收到以下错误:
[error] ExistentialTypes.scala:12:24: not found: type _$2
[error] case _: Option[_ <: ChildA] => "ChildA"
[error] ^
[error] ExistentialTypes.scala:13:24: not found: type _$3
[error] case _: Option[_ …Run Code Online (Sandbox Code Playgroud) scala pattern-matching existential-type scalac scala-compiler
scala ×10
scala-compiler ×10
scalac ×3
implicit ×1
scala-2.11 ×1
scala-2.12 ×1
scala-macros ×1
type-bounds ×1