[英]Simulacrum in Scalafiddle: exception during macro expansion
我想用擬像在Scalafiddle,如:
import simulacrum._
@typeclass trait Ordering[T] {
def compare(x: T, y: T): Int
@op("<") def lt(x: T, y: T): Boolean = compare(x, y) < 0
@op(">") def gt(x: T, y: T): Boolean = compare(x, y) > 0
}
這給了我以下錯誤:
ScalaFiddle.scala:3: error: exception during macro expansion:
scala.reflect.macros.TypecheckException: not found: type op
at scala.reflect.macros.contexts.Typers.$anonfun$typecheck$3(Typers.scala:32)
...
這是小提琴: https : //scalafiddle.io/sf/vT0X9FR/4
我錯過了什么嗎?
您的代碼沒有任何問題,問題在於ScalaFiddle。
如果我嘗試在scastie (類似Scala的Web IDE)中運行代碼,並打印出由它生成的類型樹,您可以看到以下內容:
|-- class Playground BYVALmode-EXPRmode (site: package <empty>)
| |-- new op("<") EXPRmode (silent: class Playground)
您可以看到scastie導致生成的代碼被包裝在Playground
類中,該類未在您的代碼中定義,而是由Web IDE為您提供。
如果我在IDEA中編譯相同的示例,我會看到以下內容:
|-- new op("<") EXPRmode (silent: package github)
| |-- new op BYVALmode-EXPRmode-FUNmode-POLYmode (silent: package github)
正如您所看到的,沒有包含由simulacrum創建的op
類型。 由於這種包裝,simulacrum無法找到它生成的op
類型,因為它在編譯時的完整命名空間是Playground.op
。
要避免這種情況並將其作為解決方法,請將您的特征包裝在對象中:
import simulacrum._
object Foo {
@typeclass trait Ordering[T] {
def compare(x: T, y: T): Int
@op("<") def lt(x: T, y: T): Boolean = compare(x, y) < 0
@op(">") def gt(x: T, y: T): Boolean = compare(x, y) > 0
}
@typeclass trait Numeric[T] extends Ordering[T] {
@op("+") def plus(x: T, y: T): T
@op("*") def times(x: T, y: T): T
@op("unary_-") def negate(x: T): T
def zero: T
def abs(x: T): T = if (lt(x, zero)) negate(x) else x
}
import Foo.Numeric.ops._
def signOfTheTimes[T: Numeric](t: T): T = -(t.abs) * t
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.