如何让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
答案 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的括号。