scalabook

Форк
0
/
parameter-untupling.md 
87 строк · 3.2 Кб

Распаковка параметров

Допустим есть список кортежей, например:

val xs: List[(Int, Int)] = List((1, 2), (3, 4))

и необходимо изменить xs

в List[Int]
, чтобы каждая пара чисел была сопоставлена с их суммой. Ранее лучший способ сделать это - с помощью декомпозиции сопоставления с образцом:

xs map {
case (x, y) => x + y
}

Хотя это правильно, это также неудобно и сбивает с толку, поскольку case

предполагает, что сопоставление с образцом может завершиться ошибкой. Как более короткая и понятная альтернатива, Scala 3 теперь позволяет

xs.map {
(x, y) => x + y
}
// res0: List[Int] = List(3, 7)

или, что то же самое:

xs.map(_ + _)
// res1: List[Int] = List(3, 7)

а также

def combine(i: Int, j: Int) = i + j
xs.map(combine)
// res2: List[Int] = List(3, 7)

Как правило, значение функции с n > 1

параметрами упаковывается в функциональный тип формы ((T_1, ..., T_n)) => U
, если это ожидаемый тип. Параметр кортежа декомпозируется, и его элементы передаются непосредственно базовой функции.

Более конкретно, адаптация применяется к несовпадающему списку формальных параметров. В частности, адаптация не является преобразованием между типами функций. Поэтому не принимается:

val combiner: (Int, Int) => Int = _ + _
xs.map(combiner)
// error:
// Found: (repl.MdocSession.MdocApp.combiner : (Int, Int) => Int)
// Required: ((Int, Int)) => Nothing
// xs.map(combiner)
// ^^^^^^^^

Значение функции должно быть явно сложены:

xs.map(combiner.tupled)
// res4: List[Int] = List(3, 7)

Преобразование может быть предусмотрено в пользовательском коде:

import scala.language.implicitConversions
transparent inline implicit def `fallback untupling`(f: (Int, Int) => Int): ((Int, Int)) => Int =
p => f(p._1, p._2) // use specialized apply instead of unspecialized `tupled`
xs.map(combiner)

Попытка распаковки параметров предпринимается до применения преобразований, поэтому преобразование области действия не может нарушить распаковку.


Ссылки:

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.