Question

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.

Was it helpful?

Solution

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)
                                  ^

OTHER TIPS

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))
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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top