隐式转换、类型参数、重载和匿名函数语法

Implicit conversions, type parameters, overloading, and anonymous functions syntax

所以,我试图 "pimp" 我的 Futures(除其他外)有点像这样:

implicit class Pimp[T](val x: T) extends AnyVal  {
  def ->>[R](f: T => R): R = f(x)
  def ->>[R](r: => R): R = r
  def <<-(f: T => Unit): T = f.andThen(_ => x).apply(x)
  def <<-(f: => Unit): T = <<- { _ => f }
}

出于某种原因,当我现在尝试这样做时:

Future(1) ->> { Await.result(_, 1 seconds) }

失败 error: missing parameter type for expanded function ((x) => Await.result(x, 1.seconds))

但这行得通:

Future(1) <<- { Await.result(_, 1 seconds) }

所以,问题是第一种情况出了什么问题。我做错了什么,以及如何让它发挥作用。 我什至尝试过这个(根本不是我想要的,因为它太冗长了):Future(1) --> { case x: Future[Int] => Awayt.result(_, 1 seconds) },但由于某种原因即使这样也失败了(仍然说参数类型未知 - 如果我明确指定它???)

我怀疑,第一种情况和第二种情况的区别在于 ->> 有一个类型参数,而 <<- 没有......但即使这样 Future(1) ->>[Int] { Await.result(_, 1 seconds) } 仍然没有工作:(

更新 好的,所以,我找到了一种工作方式:

Future(1) ->> { (f:Future[Int]) => Await.result(f, 1 seconds) }

这有点违背了我隐含的目的,因为它太冗长了:( 有什么方法可以让它推断参数类型而无需像在其他情况下那样拼写出来吗?

更新 2 还有一件事。从 Pimp 中删除 ->> 的重载 "flavor" 使另一种情况有效。也就是说,如果我只离开

def ->>[R](f: T => R): R = f(x)

定义Pimp,然后

Future(1) ->> { Await.result(_, 1 seconds) }

按预期完美运行。

想了一会儿,我认为问题是在重载的情况下 foo ->> { _ => bar } 是不明确的:它可能意味着 "return bar",或 "return a function foo => bar"。然而,这并不能解释为什么 foo ->>[Bar] { _ => bar } 不起作用。

您可以将电话缩短至 Future(1) ->> { Await.result(_: Future[Int], 1 seconds) }。不完美,但比您的更新 1 更好。更好的方法是避免 "pimped" 方法中的重载:不出所料,它会使类型推断复杂化。

仔细阅读 http://www.scala-lang.org/files/archive/spec/2.11/06-expressions.html 后,似乎指定 [Int] 不应该 工作:

  1. 整个表达式是一个函数应用(6.6)。

  2. 由于Future(1).->>超载,我们转到6.23。

    1. 备选方案集A是->>引用的成员集; [Int]没有考虑进去,因为段里讲的是"identifier or selection e",选择的是Future(1).->>.

    2. shape({ Await.result(_, 1 seconds) })Any => Nothing.

    3. "Let B be the set of alternatives in A that are applicable to expressions (e1,…,en) of types (shape(e1),…,shape(en))"。 A中的两种方法都是适用于Any => Nothing(如你所说,"it could mean "return吧,或者"return a function foo => bar")。所以我们转到 "Otherwise, let S1,…,Sm be the vector of types obtained by typing each argument with an undefined expected type" 并且此键入失败。

    4. 对于<<-的情况,=> Unit是不适用的(因为这一步期望的类型不是Unit , 值丢弃不会发生).

但它非常微妙,以至于我在编写此更新时改变了两次想法;我认为我现在明白了。