4

I recently started learning Scala and came across currying. From an answer in this post, this code snippet

def sum(a: Int)(b: Int) = a + b 

expands out to this

def sum(a: Int): Int => Int = b => a + b 

Then I saw a snippet from scala-lang, which shows it's possible to write something like this to emulate a while loop

 def whileLoop (cond : => Boolean) (body : => Unit) : Unit = { if (cond) { body whileLoop (cond) (body) } } 

Out of curiosity, I tried to expand this out, and got this

 def whileLoop2 (cond : => Boolean) : (Unit => Unit) = (body : => Unit) => if (cond) { body whileLoop2 (cond) (body) } 

But there seems to be some syntax that I'm missing because I get an error

error: identifier expected but '=>' found. (body : => Unit) => ^ 

What is the proper way to expand out the emulated while loop?

1 Answer 1

6

The tricky part is dealing with the parameterless function or "thunk" type => Unit. Here is my version:

def whileLoop2 (cond: => Boolean): (=> Unit) => Unit = body => if (cond) { body whileLoop2 (cond)(body) } var i = 5 val c = whileLoop2(i > 0) c { println(s"loop $i"); i -= 1 } 

It appears that you can annotate the return type with (=> Unit) => Unit, but you cannot annotate (body: => Unit), so you have to rely on the type inference here.

Sign up to request clarification or add additional context in comments.

2 Comments

Is it possible change this solution such that i can write whileLoop2 (i > 0) { println "..." } instead of whileLoop2(i > 0) { () => println "..." } ? The example in the scala-lang page doesn't have the extra () => bit when using their emulated while loop.
Sorry, it is possible to use parameterless function arguments. See my edited version.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.