Scala by Example - проблемы с каррингом - PullRequest
2 голосов
/ 22 декабря 2011

Не уверен, как правильно сформулировать вопрос, существует проблема с каррированием в примере сортировки слиянием из книги Scala by Example на стр. 69. Функция определяется следующим образом:

def msort[A](less: (A, A) => Boolean)(xs: List[A]): List[A] = {
  def merge(xs1: List[A], xs2: List[A]): List[A] =
    if (xs1.isEmpty) xs2
    else if (xs2.isEmpty) xs1
    else if (less(xs1.head, xs2.head)) xs1.head :: merge(xs1.tail, xs2)
    else xs2.head :: merge(xs1, xs2.tail)
  val n = xs.length/2
  if (n == 0) xs
  else merge(msort(less)(xs take n), msort(less)(xs drop n))
}

, а затеместь пример того, как создать из него другие функции путем каррирования:

val intSort = msort((x : Int, y : Int) => x < y)
val reverseSort = msort((x:Int, y:Int) => x > y)

однако эти две строки дают мне ошибки о недостаточном количестве аргументов.И если я сделаю так:

val intSort = msort((x : Int, y : Int) => x < y)(List(1, 2, 4))
val reverseSort = msort((x:Int, y:Int) => x > y)(List(4, 3, 2))

, это будет работать.Зачем?Может кто-нибудь объяснить?Похоже, что книга действительно устарела, поскольку это не первый случай такого несоответствия в ее примерах.Кто-нибудь может указать на что-то более реальное для чтения?(лучше бесплатная электронная книга).

1 Ответ

6 голосов
/ 22 декабря 2011

Мой компилятор (2.9.1) согласен, здесь, похоже, ошибка, но компилятор говорит вам, что делать:

error: missing arguments for method msort in object $iw;
follow this method with `_' if you want to treat it as a partially applied function

Итак, это работает:

val intSort = msort((x : Int, y : Int) => x < y) _

Поскольку подразумевается тип intSort, компилятор, похоже, не знает, собирались ли вы применить частично или пропустили аргументы.

_ можно опустить, когда компилятор может определить из ожидаемого типа, что частично примененная функция - это то, что предназначено. Так что это тоже работает:

val intSort: List[Int] => List[Int] = msort((x: Int, y: Int) => x < y)

Это, очевидно, более многословно, но чаще вы будете использовать это без каких-либо дополнительных шаблонов, например, если msort((x: Int, y: Int) => x < y) был аргументом функции, тип параметра которой уже известен как List[Int] => List[Int].


Редактировать: Страница 181 текущей редакции Спецификации языка Scala упоминает ужесточение правил для неявного преобразования частично примененных методов в функции начиная с Scala 2.0. Существует пример неверного кода, очень похожего на код в Scala на примере , и он описывается как «ранее действующий код».

...