Scala - 递归视图边界

时间:2013-03-11 22:40:34

标签: scala

如何让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

2 个答案:

答案 0 :(得分: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

答案 1 :(得分: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的括号。