1

I am new to scala. I don't understand the compilation error for the below code:

def delayed( t:(Int)=> Int):Unit={
    println("In delayed method")
    var y=t; 
    println(y)
}

def time(x:Int):Int={
    x*2
}

and when I call

delayed(time(8))

I get the following error:

scala> delayed(time(8))
<console>:15: error: type mismatch;
found   : Int
required: Int => Int
delayed(time(8))
        ^

Please explain what is the issue? Please also suggest a good link to understand functions and function literals in scala. I am not able to understand fully.

Thanks so much

Edit:

Please tell the difference between

        def delayed( t: Int => Int):Unit = {

and

        def delayed(t: =>Int):Unit {

and

        def delayed(t:=>Int):Unit { (without space b/w ":" and "=>"))
Surbhi Jain
  • 369
  • 1
  • 11
  • 1
    you probably just meant `def delayed(t: => Int):Unit` which means `t` has type `Int` but it's a **call by name** argument, which means it only gets evaluated when used inside the method body, and not when method is _called_. What you did is different - as answered below, `t` is not an `Int` but a function `Int => Int` – Tzach Zohar Oct 19 '16 at 07:50
  • I think you should ask this in another question. If you change the question, all the answers below become invalid. – ntalbs Oct 19 '16 at 14:41
  • Sorry @ntlabs. I have asked another question. Thanks – Surbhi Jain Oct 19 '16 at 14:57

2 Answers2

2

Your function delayed expects function as an argument, however, you passed Int. That's why you get the error.

The type of the argument of delayed is Int=>Int, which means it is a function accept one Int as an argument and returns Int.

Your function time is Int=>Int function, however, when you pass time(8) to the delayed function, time(8) will be evaluated before it is passed to delay, and the evaluation result is just an Int.

scala> delayed(time(8))
<console>:14: error: type mismatch;
 found   : Int
 required: Int => Int
       delayed(time(8))
                   ^

If you pass the time function only, it will work.

scala> delayed(time)
In delayed method
<function1>

If you want to pass time(8) as a function argument, you should change time function to return function:

scala> def time(x:Int) = () => x*2

You also need to modify delayed function like the below:

def delayed(t:()=>Int) {
    println("In delayed method")
    var y=t();
    println(y)
}

Then you can pass time(8) to delayed.

scala> delayed(time(8))
In delayed method
16

Or you can use call by name as @Tzach mentioned in the comment.

scala> def delayed(t: =>Int) {
     |   println("In delayed method")
     |   var y = t
     |   println(y)
     | }
delayed: (t: => Int)Unit

scala> def time(t:Int) = t*2
time: (t: Int)Int

scala> delayed(time(8))
In delayed method
16
ntalbs
  • 28,700
  • 8
  • 66
  • 83
  • Thank you so much. But, is there a way I can pass time function in delayed function without it being evaluated before? Can you pls tell the syntax to do the same. – Surbhi Jain Oct 19 '16 at 07:48
  • How can I pass an argument to the time method? – Surbhi Jain Oct 19 '16 at 07:50
  • Thanks for such an informative reply. One more thing, please, as you wrote def delayed(t: =>Int) , the code works but if I do not give a space b/w ":" and "=>", the code fails giving a compilation error. Does the space indicate something? Can you please tell what does the arguments in this line means- def delayed(t: =>Int)? Does this mean that there is a function which will be passed in delayed which can have any number of arguments and which returns an Int? Can it be used for any number of argument or can we specify a particular no. of argument for the function which we will pass? Thnks a lot – Surbhi Jain Oct 19 '16 at 12:26
1

Method delayed expects a function with Input param Int and return type Int But in your example you are passing result of time function.

This will solve your issue.

delayed(time)
Balaji Reddy
  • 5,576
  • 3
  • 36
  • 47