我正在尝试String
使用一种新的 apply 方法进行扩展,该方法让我可以在其上应用高阶函数。例子:
case class A(s:String, f: List[String] => List[String])
val f: List[String] => List[String] = { ... stuff ... }
"foo"{f} // == A("foo", f)
所以我已经定义了一个从 String 到带有一个List[String] => List[String]
函数的 apply 方法的隐式转换。
implicit def c(s:String) = new {
def apply(f: List[String] => List[String]) = A(s, f)
}
但是当我尝试使用它时,转换与 Predef 中转换String
为StringOps
.
scala> "foo"{f}
<console>:19: error: type mismatch;
found : java.lang.String
required: ?{val apply: ?}
Note that implicit conversions are not applicable because they are ambiguous:
both method c in object $iw of type (s: String)java.lang.Object{def apply(f: (List[String]) => List[String]): A}
and method augmentString in object Predef of type (x: String)scala.collection.immutable.StringOps
are possible conversion functions from java.lang.String to ?{val apply: ?}
"foo"{f}
^
为什么它寻找一个通用的应用方法(required: ?{val apply: ?}
)而不是一个接受我的类型的参数(List[String] => List[String]
)?
编辑:
我通过避免使用裸字符串来表达变量来解决这个问题(在我正在研究github的项目中)。所以现在它看起来像这样:
case class param(val v: String) {
def apply(f: Emit.Selector) = Variable(v, f)
}
val $foo = param("foo")
foo{selector} // works fine
而且我不需要使用隐式。
进一步更新
似乎scala在搜索时确实在implicits的结果类型中寻找类型参数。我让它工作,但函数参数和应用方法的场景不起作用。怎么来的?
scala> class A()
defined class A
scala> class B()
defined class B
scala> implicit def one(s:String) = new {
| def a(a:A) = s + " A"
| }
one: (s: String)java.lang.Object{def a(a: A): java.lang.String}
scala> implicit def another(s:String) = new {
| def a(b:B) = s + " B"
| }
another: (s: String)java.lang.Object{def a(b: B): java.lang.String}
scala> "hello" a new A
res1: java.lang.String = hello A
scala> "hello" a new B
res2: java.lang.String = hello B