1

while reviewing a tutorial I saw a code piece, to understand this try to write a sample function and call it.

since I am new to scala do not find where to start.

val flow3: Flow[Int, Int, NotUsed] = Flow[Int].statefulMapConcat {
    () =>
    var sequence = 0
    println("statefulMapConcat func call")
    i =>
      sequence = sequence + i
      List(sequence)
  }

in the above two things are strange for me

  1. () => why no parameter
  2. () => and i => // are they parameter, what kind of style is this. which is calling actual function. and how we can write a function to call this

definition is :

  def statefulMapConcat[T](f: () ⇒ Out ⇒ immutable.Iterable[T]): Repr[T] =
    via(new StatefulMapConcat(f))

my tries!!

  def suffix(x: String): String = x + ".zip"
  // not sure this is true
  def test1(f: String ⇒ String ⇒ String): String = f("a1")("a2") + "a3"
  // not sure this is also a true definition
  def test2(f: String ⇒ String ⇒ String): String = f + "a4"


  // compile is okay but can not call this
  var mytest= test1{
    a => a + "a5"
    b => b + "a6"
  }

  // giving even compile time error
  test(suffix(suffix("")))
farukonder
  • 35
  • 8

1 Answers1

0
var mytest= test1{
   a => a + "a5"
   b => b + "a6"
}

In this examble you can't call mytest because "mytest" is not a function but result of "test1" function evaluation instead. "mytest" is a string value. So you can replace this code with the following and this would still compile:

 var mytest: String= test1{
   a => a + "a5"
   b => b + "a6"
}

Your second example has another problem. You are truing to call "test" function passing result of evaluated "suffix(suffix(""))" which is string.

To make it compiles you need to create function that returning function and then pass it to "test"(1 or 2)

  def functionReturiningFunciton(s:String):String=>String = (k) => suffix(suffix(""))
  val f: String => String => String = functionReturiningFunciton // convert to value

  test1(f)
  test2(f)

or you can even pass "functionReturiningFunciton" directly, because it will be converted to val automatically

  def functionReturiningFunciton(s:String):String=>String = (k) => suffix(suffix(""))

  test1(functionReturiningFunciton)
  test2(functionReturiningFunciton)

or even like this

 test1(s => k => suffix(suffix("")))

Note. When you do this:

var mytest= test1{
  a => a + "a5"
  b => b + "a6"
}

If you de-sugar your code. You are actually doing this:

def someFunction(a:String):String=>String = {
  a + "a5" // this is evaluated but ignored 
  b => b + "a6" //this is what returned by someFunction
}

var mytest:String= test1{someFunction}

definition is :

def statefulMapConcat[T](f: () ⇒ Out ⇒ immutable.Iterable[T]): Repr[T] = via(new StatefulMapConcat(f))

Function statefulMapConcat takes as a parameter another function that has zero parameters and returns another function that takes parameter with type "Out" and returns Iterable[T]

Bogdan Vakulenko
  • 3,380
  • 1
  • 10
  • 25
  • thanks Bogdan! its put a great light on my doubts. if you mind to answer could I ask one more thing based on your answer ? `var mytest: String= test1{ a => a + "a5" b => b + "a6" }` is utilizing first parameter "a" and can be used like this : `var mytest: String= test1{ a => var c = a + "a5" b => c + b + "a6" }` .but how about this single line thing below, how can I extend this function to utilize the first parameter "s" somewhere ? `def functionReturiningFunciton(s:String):String=>String = (k) => suffix(suffix(""))`. "s" to in first function like the above. thanksinadvance. – farukonder Aug 03 '18 at 15:24
  • @farukonder if I understand you question correctly, you can use "s" and "k" in the body of the function. For example like this: def functionReturiningFunciton(s:String):String=>String = (k) => suffix(suffix(s+k)) – Bogdan Vakulenko Aug 03 '18 at 15:54
  • actually, I am trying to understand if possible to write something in single line way which first functions result is being used in second function, something like : `def functionReturiningFunciton(s:String):String=>String = (s) => var c = "s" + "bla"; (k) => suffix(c)`. `(k) => suffix(suffix(s+k))` in this case there is no benefit of using funtionreturninganotherfunction, actually its a normal function. thanks :) – farukonder Aug 03 '18 at 16:07
  • @farukonder like this? def functionReturiningFunciton(s:String):String=>String = {var c = s + "bla"; (k) => suffix(c)} – Bogdan Vakulenko Aug 03 '18 at 16:11
  • I bother you too much but can I ask one more a simple question for you ? if I have a function like this: ` def executeXTimes(callback:() => Unit, numTimes: Int) { for (i <- 1 to numTimes) callback() }` then how can I call this in above first style like `executeXTimes { () => println("Hello") ,3 }`. try to send "numTimes" as a parameter. pls pls pls :) "besides this way `val sayHello = () => println("Hello") executeXTimes(sayHello, 3)` function as parameter body along with other parameter. " – farukonder Aug 03 '18 at 16:50
  • @farukonder just replace curly brackets with regular brackets: executeXTimes ( () => println("Hello") ,3 ) . Curly brackets are reserved for more specific use cases when you pass single function parameter into function. You can read something about it here https://stackoverflow.com/questions/4386127/what-is-the-formal-difference-in-scala-between-braces-and-parentheses-and-when – Bogdan Vakulenko Aug 03 '18 at 17:04