0

如何让 scala 编译器递归查找隐式视图?

type Expression = () => String

implicit def constant(s: String): Expression = () => s

implicit def evaluation[A <% Expression](exprs: Seq[A]): Expression = () => exprs match {
  case "concat" :: args => args.map(_.apply()).mkString
}

Seq("concat", "foo", "bar")() // This works
Seq("concat", "foo", Seq("concat", "bar", "baz"))() // No implicit view available from java.lang.Object => () => String.

我知道最后一个序列具有Object没有隐式视图的通用类型,但是如何在不诉诸动态模式匹配的情况下定义类型安全的AnyRef

在 Scala 2.9.2 中尝试过

4

2 回答 2

2

由于内容混合,类型推断发现您有一个Seq[Any]。最简单的解决方案是帮助编译器并告诉它你有一个Seq[Expression]

Seq[Expression]("concat", "foo", Seq("concat", "bar", "baz"))()

编辑

这就是你可以用元组解决它的方法:

type Expression = () => String

implicit def constant(s: String): Expression = () => s

implicit def evaluation[A <% Expression, B <% Expression, C <% Expression](
  exprs: (A, B, C)): Expression = 
  () => exprs match {
    case ("concat", arg1, arg2) => arg1() + arg2()
  }

("concat", "foo", "bar")()                      //> res0: String = foobar
("concat", "foo", ("concat", "bar", "baz"))()   //> res1: String = foobarbaz
于 2013-03-11T23:19:15.070 回答
0

我还想知道为什么 scala 编译器无法弄清楚内部 Sequence 是一个表达式——我想,你只是忘记了一些括号——它们是:

Seq("concat", "foo", Seq("concat", "bar", "baz")())() // added inner brackets

编辑

但是,我明白您的观点-这也行不通:

val x: Expression = Seq("concat", "foo", "bar") // This works
val y: Expression = Seq("concat", "foo", x) // No implicit view available - again

所以 - 这里也有必要为 x 提供括号。

于 2013-03-12T05:14:16.200 回答