Синтаксис для частичного применения карри функций с обратно-ассоциативной инфиксной нотацией - PullRequest
5 голосов
/ 12 октября 2011

Другими словами, есть ли веская причина, почему это не должно компилироваться?

def f(xs: List[Int]) = xs.foldLeft(0) _  // OK
def f(xs: List[Int]) = (xs :\ 0) _       // OK
def f(xs: List[Int]) = (0 /: xs) _

<console>:15: error: missing arguments for method /: in trait TraversableOnce;
follow this method with `_' if you want to treat it as a partially applied function

Вот некоторые обходные пути:

def f(xs: List[Int]) = xs./:(0) _
def f(xs: List[Int]): ((Int, Int) => Int) => Int = (0 /: xs)

но мой вопрос в основном о правильномСинтаксис в целом.

Ответы [ 2 ]

2 голосов
/ 14 октября 2011

Я исправил это только сейчас, но пока не могу проверить, потому что это требует внесения изменений в спецификацию.

scala> def f(xs: List[Int]) = (0 /: xs) _
f: (xs: List[Int])(Int, Int) => Int => Int

scala> f(1 to 10 toList)
res0: (Int, Int) => Int => Int = <function1>

scala> res0(_ + _)
res1: Int = 55

Проблема в том, что спецификация определяет "e1 op e2", если операция верна-ассоциативен, чтобы быть {val x = e1;e2.op (x)} по причинам, которые мне не очевидны, поскольку более простой e2.op (e1) решает эту проблему среди других, например https://issues.scala -lang.org / browse / SI-1980 .Я сделаю запросы.

2 голосов
/ 12 октября 2011

Похоже на ошибку компилятора. Я проверил это выражение на разных версиях Scala и получил:

def f(xs: List[Int]) = (0 /: xs) _

Он ведет себя одинаково для 2.9.1.final и 2.8.2.final, но для 2.7.7.final выдает другое сообщение об ошибке (Iterable против TraversableOnes), но я думаю, что это из-за редизайна библиотеки коллекций в более старых версиях.

def f(xs: List[Int]) = (0 /: xs) _
<console>:4: error: missing arguments for method /: in trait Iterable;
follow this method with `_' if you want to treat it as a partially applied function

Выражение, которое я упомянул в комментарии, ведет себя по-разному для разных версий scala.

def f(xs: List[Int]): (Int, Int) => Int => Int = (0 /: xs)

scala 2.9.1.final:

 found   : (Int, Int) => Int => Int
 required: (Int, Int) => Int => Int

Действительно запутанное сообщение компилятора, определенно ошибка.

scala 2.8.2.final:

 found   : => ((Int, Int) => Int) => Int
 required: (Int, Int) => (Int) => Int

Странно => в начале, по сравнению с 2.7.7. Конечный результат выглядит как регрессия.

scala 2.7.7.final:

 found   : ((Int, Int) => Int) => Int
 required: (Int, Int) => (Int) => Int

found вроде бы правильно, но код все еще не работает.

Я искал на scala bugtracker похожие проблемы, но не смог найти ничего подходящего. Думаю, достаточно создать заявку (или две? Похоже, эти две ошибки не связаны).

...