понимание scala: каррирование

Недавно я начал изучать Scala и наткнулся на каррирование. Из ответа в этом post этот фрагмент кода

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

расширяется до этого

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

Затем я увидел фрагмент из scala-lang, который показывает можно написать что-то подобное, чтобы эмулировать цикл while

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

Из любопытства я попытался расширить это, и получил это

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

Но, кажется, есть какой-то синтаксис, который мне не хватает, потому что я получаю сообщение об ошибке

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

Как правильно расширить эмулируемый цикл while?


person azelo    schedule 29.09.2014    source источник


Ответы (1)


Сложная часть связана с функцией без параметров или типом «преобразователя» => Unit. Вот моя версия:

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 }

Похоже, что вы можете аннотировать возвращаемый тип с помощью (=> Unit) => Unit, но вы не можете аннотировать (body: => Unit), поэтому здесь вам придется полагаться на вывод типа.

person 0__    schedule 29.09.2014
comment
Можно ли изменить это решение таким образом, чтобы я мог писать whileLoop2 (i › 0) { println ... } вместо whileLoop2 (i › 0) { () =› println ... } ? В примере на странице scala-lang нет дополнительного бита () =› при использовании их эмулируемого цикла while. - person azelo; 30.09.2014
comment
К сожалению, можно использовать аргументы функций без параметров. Смотрите мою отредактированную версию. - person 0__; 30.09.2014