- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在为 Scala 开发 servant-server
端口。这个想法是使用类型类解析来归纳构建可以处理请求的函数。我遇到了一些我不太明白的奇怪推理问题。
object Servant {
class :>[Path, A]
trait HasServer[A] {
type ServerT
def route(a: ServerT): String
}
implicit val unitServer = new HasServer[Unit] {
type ServerT = String
def route(str: ServerT): String = str
}
implicit def subServer[A, Sub](implicit sub: HasServer[Sub]) = new HasServer[A :> Sub] {
type ServerT = A => sub.ServerT
def route(handler: ServerT): String = "handler"
}
}
有了上面的内容,下面的编译就失败了:
val foo = implicitly[HasServer[Int :> Unit]]
implicitly[=:=[Int => String, foo.ServerT]]
错误是:
servant.scala:33: error:
Cannot prove that Int => String =:= Main.$anon.Servant.foo.ServerT.
但是,如果我通过以下方式直接实例化 HasServer[Int :> Unit]
,它将编译:
val foo = new HasServer[Int :> Unit] {
type ServerT = Int => unitServer.ServerT
def route(handler: ServerT): String = handler(10)
}
我怎样才能编译它?谢谢!
最佳答案
问题都出在implicitly
的定义上...
def implicitly[T](implicit e: T) = e
implicitly[T]
只会给你一个输入为 T
的值, 没有比这更精确的了。在上面的例子中,这是 HasServer[Int :> Unit]
其中,至关重要的是,留下成员类型 ServerT
不受约束。
这通常通过为每个类型类定义一个伴生对象来解决 apply
保留所需细化的方法,例如,
object HasServer {
def apply[T](implicit hs: HasServer[T]):
HasServer[T] { type ServerT = hs.ServerT } = hs
}
这里的结果类型有点笨拙,所以将它与“Aux”模式结合起来也很常见,
object HasServer {
type Aux[T, S] = HasServer[T] { type ServerT = S }
def apply[T](implicit hs: HasServer[T]): Aux[T, hs.ServerT] = hs
}
无论如何,这在其他地方可能会派上用场。
我们可以看到这对 REPL 上的推断类型产生的影响,
scala> implicitly[HasServer[Int :> Unit]]
res0: Servant.HasServer[Servant.:>[Int,Unit]] = ...
scala> HasServer[Int :> Unit]
res1: Servant.HasServer[Servant.:>[Int,Unit]]{type ServerT = Int => String} = ...
此细化将被推断为 val 定义的类型,因此现在您将获得所需的结果,
scala> val foo = HasServer[Int :> Unit]
foo: Servant.HasServer[Servant.:>[Int,Unit]]{type ServerT = Int => String} = ...
scala> implicitly[=:=[Int => String, foo.ServerT]]
res2: =:=[Int => String,foo.ServerT] = <function1>
implicitly
的定义有多种方式可以改进以避免这个问题。下面是最直接的引用类型,
def implicitly[T <: AnyRef](implicit t: T): t.type = t
如果literal types启用后我们可以删除 <: AnyRef
为所有类型绑定(bind)并定义它,
def implicitly[T](implicit t: T): t.type = t
shapeless 提供了一个 the[T]
运算符,其行为与后者通过宏类似。
关于Scalac 无法推断归纳构建的路径相关类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39954029/
我正在为 Scala 开发 servant-server 端口。这个想法是使用类型类解析来归纳构建可以处理请求的函数。我遇到了一些我不太明白的奇怪推理问题。 object Servant {
我设置了 -Xfatal-warnings我的 SBT 构建中的编译器标志,果然这段代码不能编译: package example sealed trait Errors object Errors
在GCC compiler we see几个'intermediate languages ':RTL , GENERIC and GIMPLE . This answer hints在 scalac
scalax -Xlint 帮助提供以下信息: $ scalac -Xlint:help Enable or disable specific warnings adapted-args
我想拆分我的 scalac插件到多个文件中。这听起来很简单,但由于来自 import global._ 的路径相关类型问题,我还没有设法实现它。线。 这是 Lex Spoon 的示例插件: packa
我正在将一个大型项目升级到 2.10.4 到 2.11.4。我的编译器崩溃了,无论如何要显示 的名称吗?源文件 那是导致崩溃的原因吗?我可以使用“last everitt/compile:compil
为什么这不能编译? 给出的错误是 class SomeElement needs to be abstract, since method eval in trait Element of type
我刚刚注意到我的代码中有一个错误,我在其中创建了一个新变量,但后来未能实际使用它。 我认为 scalac 会告诉我我的新变量未使用,但情况似乎并非如此,在搜索了少量谷歌搜索/手册页后,我找不到任何关于
在像这样的伴生对象上定义 val 时: object Foo { val bar = 3 } Scala 生成静态 final方法: $ scalac Foo.scala && javap Foo p
我们在以下情况下使用 Scalac -Xfatal-warnings 时会遇到问题: 宏内部使用的隐式值 宏自动生成的内部值 在这两种情况下,我们都看到 Scalac 无法编译,因为它检测到一些值未被
根据 Scala 教程,我们需要先使用 scalac filename.scala 编译 Scala 代码,然后再使用 scala filename 执行它。但是当我像 scala filename.
在 Martin Odersky 的“Programming in scala”一书中,它解释了 scalac 看起来很慢的原因(第 114 页): The reason is that every
我知道使用 -Werror 和 -Xfatal-warnings 我可以将警告作为错误,但是否仍然可以在编译输出中看到所有警告,但只会让其中的一些变成错误? 最佳答案 我不这么认为,单独使用 scal
我写了以下非常简单的测试: import scala.collection.immutable.HashSet class Test { def m() = { var s = new H
如果我运行“scalac -explaintypes”并看到类似的内容: Nothing NoType (base ne tr1) && base <: X?" mean?,我们在Sta
这是一段代码示例,第一印象看起来像 scalac。可以很容易地优化掉: val t0 = System.nanoTime() for (i <- 0 to 1000000000) {} val t1
首先。考虑以下代码 scala> val fail = (x: Any) => { throw new RuntimeException } fail: Any => Nothing = scala
我有一个 ScalaTest 2 类,它扩展了 GeneratorDrivenPropertyChecks,还间接扩展了 FeatureSpec 和 Matchers(通过我写的扩展那些的特征两个类)
我创建了一个小示例程序来尝试找出为什么没有编译更大的程序。 val o1: Ordered[Int] = 1 val o2: Ordered[Int] = 2 println(o1 java.lan
我列出了今天发现的问题的简短列表。我是 scala 新手,因此我的问题可能很微不足道。 假设我们有一个这样的类: abstract class A[+T] { def foo[S >: T](x: S
我是一名优秀的程序员,十分优秀!