简体   繁体   中英

Problem with Scala Function and Call-by-Name

I am trying to loop a the second parameter (exp) in this function that uses call by name parameters. The first 3 parameters are the index, boolean to stop loop, and increment function. I am getting an output with 10 '()'s when I am trying to loop "hello world" 10 times as seen in the test code. May I get some help with what is wrong here? Thanks

def forLoop(ival: => Int, f: (Int) => Boolean, g: (Int)=>Int)(exp: => Unit): Unit = {
  if(f(ival)==false) 
    return
  else {
    println(exp)
    forLoop(g(ival),f,g)(exp)
  }
}

def f(x: Int): Boolean = { x<10 }
def g(y: Int): Int = { y+1 }
val exp: Unit = "Hello World"
forLoop(0,f,g)("Hello World")

The value "Hello World" is of type String however you are assigning it to Unit

val exp: Unit = "Hello World"

which compiler expands to

val exp: Unit = {
  "Hello World";
  ()
}

Note how () becomes the value of exp . Try changing the definition of exp to

val exp: String = "Hello World"

and second parameter list to

(exp: => String)

If you compile with compiler flag -Wvalue-discard , for example,

scala -Wvalue-discard -e 'val exp: Unit = "Hello World"'

you will get a warning

warning: discarded non-Unit value
val exp: Unit = "Hello World"
                ^

I think this meets your requirements.

def forLoop(ival: => Int, f: =>Int => Boolean, g: =>Int=>Int
           )(exp: => Unit): Unit =
  if (f(ival)) {
    exp
    forLoop(g(ival),f,g)(exp)
  }

def f(x: Int): Boolean = x<10
def g(y: Int): Int = y+1
def exp: Unit = println("Hello World")
forLoop(0,f,g)(exp)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM