Почему currying and uncurrying не подразумевается в scala

Если у меня есть функция:

f : A => B => C

Я могу определить неявное преобразование, так что это можно использовать там, где ожидается функция (A, B) => C. Это также в другом направлении.

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

Ответы

Ответ 1

Я не думаю, что что-то плохое произойдет. Преобразование абсолютно недвусмысленно. В худшем случае Scala не сможет понять, что применяется неявное преобразование.

implicit def curryImplicitly[A,B,C](f: (A, B) => C) =
  (a: A) => (b: B) => f(a, b)
implicit def uncurryImplicitly[A,B,C](f: A => B => C) =
  (a: A, b: B) => f(a)(b)

Затем снова это будет полезно.

implicit def flipImplicitly[A,B,C](f: (A, B) => C) =
  (b: B, a: A) => f(a, b)
implicit def flipImplicitlyCurried[A,B,C](f: A => B => C) =
  (b: B) => (a: A) => f(a)(b)

Но они не являются транзитивными, поэтому вам нужны эти:

implicit def flipAndCurry[A,B,C](f: (A, B) => C) =
  (b: B) => (a: A) => f(a, b)
implicit def flipAndUncurry[A,B,C](f: A => B => C) =
  (b: B, a: A) => f(a)(b)

Но теперь преобразование неоднозначно. Так что это не все розы.

Знайте, как это работает на практике. Вам могут потребоваться эквиваленты для Function3, Function4 и т.д.

Ответ 2

Вы не хотите, чтобы они были неявно доступны по умолчанию (всегда включено), потому что тогда система типов не может помочь вам, когда вы перегружены аргументами из группы похожих типов:

A => B => C
D => C      // D is allowed to be a tuple (A,B)...

(A,B) => C  // If I have this, to whom should I convert?

Часть преимуществ сильной типизации предупреждает вас, когда вы делаете что-то глупое. Пытаться слишком усердно, чтобы что-то сделать, снижает преимущества. Здесь, если конверсии выполнялись автоматически, вы не можете вызвать метод, который вы хотели вызвать.

Наличие их неявно по запросу в порядке, но это не так сложно сделать, если вам это нужно. Это то, что я использовал бы довольно редко; Я бы не поместил его в первую десятку или, возможно, даже сотню вещей, которые мне бы хотелось в библиотеке (отчасти потому, что я предпочел бы автоматическое преобразование в кортеж, а не автоматический поиск/распутывание).