scalabook

Форк
0
/
type-lambdas.md 
162 строки · 5.6 Кб

Лямбда-типы

Лямбда-тип позволяет выразить тип более высокого типа напрямую, без определения.

[X, Y] =>> Map[Y, X]

Например, приведенный выше тип определяет конструктор бинарного вида, который сопоставляет аргументы X

и Y
с Map[Y, X]
. Параметры типа лямбда-выражений могут иметь границы, но они не могут содержать аннотации вариантности +
или -
.

Пример:

type XY = [X, Y] =>> Map[Y, X]
val numbers: XY[String, Int] = Map(1 -> "first", 2 -> "second")
// numbers: Map[Int, String] = Map(1 -> "first", 2 -> "second")
numbers(1)
// res0: String = "first"

Проверка типа

Лямбда-тип, например, [X] =>> F[X]

определяет функцию от типов к типам. Параметры могут иметь ограничения. Если параметр ограничен, как [X >: L <: U] =>> F[X]
, то проверяется, что аргументы параметров соответствуют границам L
и U
. Только верхняя граница U
рассматривается включительно, т.е. что X
может в неё входить.

Правила подтипа

Рассмотрим два лямбда-выражения

type TL1 = [X >: L1 <: U1] =>> R1
type TL2 = [X >: L2 <: U2] =>> R2

Тогда TL1 <: TL2

, если

  • интервал типов L2 .. U2
    содержится в интервале типа L1 .. U1
    (т.е. L1 <: L2
    и U2 <: U1
    ),
  • R1 <: R2

Предполагается, что частично применяемый конструктор типа List

эквивалентен его Eta Expansion. Т.е. List = [X] =>> List[X]
. Это позволяет сравнивать конструкторы типов с лямбда-выражениями типов.

Связь с определениями параметризованного типа

Определение параметризованного типа

type T[X] = R

рассматривается как сокращение для непараметризованного определения с лямбда-типом в правой части:

type T = [X] =>> R

Если определение типа содержит аннотации вариантности +

или -
, проверяется, удовлетворяет ли лямбда аннотации вариантности. Например,

type F2[A, +B] = A => B

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

type F2 = [A, B] =>> A => B

и при этом проверяется, что параметр B

появляется ковариантно в A => B
.

Параметризованный абстрактный тип

type T[X] >: L <: U

считается сокращением для непараметризованного абстрактного типа с лямбда-выражениями типа в качестве границ.

type T >: ([X] =>> L) <: ([X] =>> U)

Однако, если L

- Nothing
, то он не параметризован, т.к. Nothing
считается нижним типом для всех видов. Например,

type T[X] <: X => X

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

type T >: Nothing <: ([X] =>> X => X)

вместо

type T >: ([X] =>> Nothing) <: ([X] =>> X => X)

Те же расширения применяются к параметрам типа. Например,

[F[X] <: Coll[X]]

рассматривается как сокращение для

[F >: Nothing <: [X] =>> Coll[X]]

Абстрактные типы и псевдонимы непрозрачных типов запоминают вариантность, с которыми были созданы. Итак, тип

type F2[-A, +B]

известно, что он контравариантен в A

и ковариантен в B
и может быть реализован только с типами, которые удовлетворяют этим ограничениям. Так же

opaque type O[X] = List[X]

O

известно, что оно инвариантно (а не ковариантно, как следует из его правой части). С другой стороны, прозрачный псевдоним

type O2[X] = List[X]

будет рассматриваться как ковариантный, X

используется ковариантно в его правой части.

Каррированные параметры типа

Тело лямбда-типа может снова быть лямбда-типом. Пример:

type TL = [X] =>> [Y] =>> (X, Y)

Ссылки:

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

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

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

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