How do I assign an instance method to a value in Scala?

Related: How to assign a function to a value in Scala?

Considering:

class Foo{
  def bar = println("bar")
  def bat = println("bat")
}

      

How do I create it fnRef

so that it points to either Foo.bar

or Foo.bat

?

def deepFunction(foos : List[Foo], fnRef : ()=>Unit) = {
  foos.map(_.fnRef) //May call either bar or bat
}  

      

Bonus: is it possible to restrict fnRef to be just methods of that signature in the Foo class?

+3


source to share


3 answers


No. :-) Instead, you write your code in terms of first class functions. What makes this nice in Scala is that it will create a function literal from a _.method

type T => R

, where T

is the type of the parameter and R

is the return type of the method.

So, _.bar

they _.bat

will do Foo => Unit

:

scala> class Foo{
     |   def bar = println("bar")
     |   def bat = println("bat")
     | }
defined class Foo

scala> def deepFunction(foos: List[Foo], fn: Foo => Unit) {
     |   foos.map(fn)
     | }
deepFunction: (foos: List[Foo], fn: Foo => Unit)Unit

scala> deepFunction(List(new Foo, new Foo), _.bar)
bar
bar

scala> deepFunction(List(new Foo, new Foo), _.bat)
bat
bat

      



What's really nice about this approach is that you can use any function, not just member functions.

scala> def bam(f: Foo) { println("bam") }
bam: (f: Foo)Unit

scala> deepFunction(List(new Foo, new Foo), bam)
bam
bam    

      

+6


source


You can get a reference to a method as a function via a partial application:

scala> val foo = new Foo
foo: Foo = Foo@5dc22e67

scala> val fun = foo.bar _
fun: () => Unit = <function0>

scala> fun()
bar

      



This also works with multiple parameter lists:

scala> class Bar { def bar(s: String, t: String) = println(s+t) }
defined class Bar

scala> new Bar().bar _
res0: (String, String) => Unit = <function2>

      

+2


source


Methods are not objects in Scala, you cannot assign names to them.

+1


source







All Articles