Force grouping of ascription on underscore in scala

六月ゝ 毕业季﹏ 提交于 2019-12-11 15:39:25

问题


I am trying to do:

MyObject.myMethod(_:MyType.myAttribute)

This fails with

type myAttribute is not a member of object MyObject

which is correct. The problem is that I want to call myMethod on myAttribute of _:MyType, not ascribe MyType:myAttribute to _. Can I somehow group the type ascription _:MyType? (_:MyType).myAttribute returns type MyType => classOf(myAttribute), which is not what I want.

Edit: I changed the title and text of this post to no longer refer to this as the associativity of the dot, which I believe was not correct.


回答1:


Are you trying to create function (m: MyType) => MyObject.myMethod(m.myAttribute) using underscore?

If so, the problem is that MyObject.myMethod((_:MyType).myAttribute) means MyObject.myMethod((m:MyType) => m.myAttribute).

You can use infix notation:

MyObject myMethod (_:MyType).myAttribute

Proof it works:

scala> case class MyType(myAttribute: Int)
defined class MyType

scala> object MyObject {
     |   def myMethod(a: Int) = a.toString
     | }
defined module MyObject

scala> MyObject myMethod (_:MyType).myAttribute
res0: MyType => java.lang.String = <function1>

scala> res0(MyType(1))
res1: java.lang.String = 1

scala> MyObject myMethod (MyType(1))
<console>:1: error: type mismatch;
 found   : MyType
 required: Int
              MyObject myMethod (_:MyType)
                                  ^



回答2:


I'm not sure whether this illustrates or answers your question, but it's true.

My guess is that you expected your a.b(_.i) to be an anon func after you add an ascription (to type the parameter).

But the subexpr foils you by there is no other expression of syntactic category Expr which is properly contained in e and which itself properly contains u. (SLS 6.23)

Also, you can use scalac -Xprint:parser to see how it's taken.

object Foo {
  def m(k: Int) = 7 * k
}
class Bar {
  val i = 5
  val What = i
}
object Bar {
  type What = Int
}

object Test extends App {
  Foo.m(_:Bar.What)
  // this is not anon func placeholder syntax...
  //Foo.m((_:Bar).What)  // _ is in a subexpr
  //Foo.m(_.i)
  // ...for this
  val f = (x: Bar) => Foo.m(x.i)
  // InfixExpr is ok
  val g = Foo m (_: Bar).i
  val b = new Bar
  println(f(b))
  println(g(b))
}

Contrast, to illustrate what is being restricted:

scala> val f: (Int,Int)=>Int = _+_
f: (Int, Int) => Int = <function2>

scala> val g: Int=>Int = if (_ > 0) 1 else 2
<console>:7: error: missing parameter type for expanded function ((x$1) => x$1.$greater(0))



回答3:


List(1,2,3).map((i: Int) => i * i)

EDIT

List(1,2,3).map((_: Int).unary_-)

EDIT 2

implicit class MyAttribute(i: Int) { def myMethod() = i * i }
List(1,2,3).map((_: Int).myMethod.unary_-)

Explanation

I used implicit class (Scala-2.10) to add myMethod on Int, after that unary "-" operation executed on result. You could add something like def wrap: MyAttribute to MyAttribute, and use it like (_: Int).wrap.method1.method2.method3.result.abs, for example.



来源:https://stackoverflow.com/questions/13831313/force-grouping-of-ascription-on-underscore-in-scala

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!