Reputation: 30085
Could you please explain to me how to write shortened version of function literal ?
I'm going through this Spray tutorial in which following code
val route: Route = { ctx => ctx.complete("yeah") }
get compressed to
val route: Route = complete("yeah")
where complete is function of RouteDirectives.
I cannot reproduce the same in my code which is
class Test
{
def testFunc(value : Int) {
println(value)
}
}
type MyType = Test => Unit
val asd : MyType = _.testFunc(10)
asd(new Test)
If I write val asd : MyType = testFunc(10)
instead I (obviously) get error
error: type mismatch;
found : Int(10)
required: Int => Unit
val asd : MyType = testFunc(10)
So I thought maybe 'complete' is also an object with apply
method. And indeed following works
val route: Route = complete.apply("yeah")
But I don't see an object. In the debugger it steps into RouteDirectives.complete
as expected.
Why ? What am I missing ?
Upvotes: 2
Views: 176
Reputation: 41646
complete
returns a function. When you call complete("yeah")
, you are supplying the "yeah"
parameter to that function (they call it the magnet).
So to do something similar you would write:
def testFunc: Int => Unit = (i: Int) => println(i)
Putting it together with calling a method on an object Test
:
def testFunc: Int => (Test => Unit) = (i: Int) => {
(test: Test) => println(i)
}
Because of the way =>
associates to the right and type inference, this could be rewritten:
def testFunc: Int => Test => Unit = i => test => println(i)
It is then either very confusing or natural (the parameters mirror the types exactly).
So when in the tutorial they say it is equivalent, the authors of the library go to some length to make it look like it is "equivalent" by returning functions, it is not something that is built-in in the Scala syntax.
Upvotes: 4
Reputation: 65
I think you had a formatting error in your code. When I first pasted your code into the REPL, the new line after "class Test" resulted in the next block being treated as an entirely separate block. Did you execute that in the REPL? The following worked for me:
scala> class Test { def testFunc(i: Int) { println(i) } }
defined class Test
scala> type MyType = Test => Unit
defined type alias MyType
scala> val asd : MyType = { t => t.testFunc(10) }
asd: Test => Unit = <function1>
scala> val asd : MyType = { _.testFunc(10) }
asd: Test => Unit = <function1>
scala> val asd : MyType = _.testFunc(10)
asd: Test => Unit = <function1>
Upvotes: 0