简体   繁体   English

Scala - 递归视图边界

[英]Scala - Recursive view bounds

How do I get scala compiler to look for an implicit view recursively? 如何让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.

I understand that the last sequence has the common type Object which has no implicit view, but how can I define a type-safe one without resorting to dynamic pattern matching of AnyRef ? 我知道最后一个序列具有公共类型的Object ,它没有隐式视图,但是如何在不借助AnyRef动态模式匹配的情况下定义类型安全的类型?

Tried in scala 2.9.2 尝试scala 2.9.2

The type-inference figured out you have a Seq[Any] because of the mixed contents. 由于混合内容,类型推断发现你有一个Seq[Any] The easiest solution is to help the compiler and tell it you have a Seq[Expression] 最简单的解决方案是帮助编译器并告诉它你有一个Seq[Expression]

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

Edit 编辑

This is how you could solve it with tuples: 这是你用元组解决它的方法:

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

I also wondered why the scala compiler couldn't figure out that the inner Sequence was an expression - I figured, you simply forgot some brackets - here they are: 我也想知道为什么scala编译器无法弄清楚内部Sequence是一个表达式 - 我想,你只是忘了一些括号 - 这里它们是:

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

Edit 编辑

I see your point however - this also does not work: 我明白你的观点 - 这也行不通:

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

so - here also it is necessary to provide the brackets for x. 所以 - 这里也有必要提供x的括号。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM