Haskell Language
Кортежи (пары, тройки, ...)
Поиск…
замечания
Haskell не поддерживает кортежи с одним компонентом изначально.
Единицы (написанные
()
) можно понимать как кортежи с нулевыми компонентами.Не существует предопределенных функций для извлечения компонентов кортежей с более чем двумя компонентами. Если вы считаете, что вам нужны такие функции, рассмотрите возможность использования пользовательского типа данных с метками записей вместо типа кортежа. Затем вы можете использовать метки записей в качестве функций для извлечения компонентов.
Построить значения кортежа
Для создания кортежей используйте скобки и запятые. Используйте одну запятую, чтобы создать пару.
(1, 2)
Используйте больше запятых для создания кортежей с большим количеством компонентов.
(1, 2, 3)
(1, 2, 3, 4)
Обратите внимание, что также можно объявлять кортежи, используя в их unsugared форме.
(,) 1 2 -- equivalent to (1,2)
(,,) 1 2 3 -- equivalent to (1,2,3)
Кортежи могут содержать значения разных типов.
("answer", 42, '?')
Кортежи могут содержать сложные значения, такие как списки или больше кортежей.
([1, 2, 3], "hello", ('A', 65))
(1, (2, (3, 4), 5), 6)
Написание типов кортежей
Используйте круглые скобки и запятые для написания типов кортежей. Используйте одну запятую, чтобы написать тип пары.
(Int, Int)
Используйте больше запятых, чтобы писать типы кортежей с большим количеством компонентов.
(Int, Int, Int)
(Int, Int, Int, Int)
Кортежи могут содержать значения разных типов.
(String, Int, Char)
Кортежи могут содержать сложные значения, такие как списки или больше кортежей.
([Int], String, (Char, Int))
(Int, (Int, (Int, Int), Int), Int)
Образец матча по кортежам
Сравнение шаблонов на кортежах использует конструкторы кортежей. Для сопоставления пары, например, мы использовали бы конструктор (,)
:
myFunction1 (a, b) = ...
Мы используем больше запятых для соответствия кортежей с большим количеством компонентов:
myFunction2 (a, b, c) = ...
myFunction3 (a, b, c, d) = ...
Шаблоны кортежей могут содержать сложные шаблоны, такие как шаблоны списков или другие шаблоны кортежей.
myFunction4 ([a, b, c], d, e) = ...
myFunction5 (a, (b, (c, d), e), f) = ...
Извлечь компоненты кортежа
Используйте функции fst
и snd
(из Prelude
или Data.Tuple
), чтобы извлечь первый и второй компоненты пар.
fst (1, 2) -- evaluates to 1
snd (1, 2) -- evaluates to 2
Или используйте сопоставление шаблонов.
case (1, 2) of (result, _) => result -- evaluates to 1
case (1, 2) of (_, result) => result -- evaluates to 2
Согласование шаблонов также работает для кортежей с более чем двумя компонентами.
case (1, 2, 3) of (result, _, _) => result -- evaluates to 1
case (1, 2, 3) of (_, result, _) => result -- evaluates to 2
case (1, 2, 3) of (_, _, result) => result -- evaluates to 3
Haskell не предоставляет стандартные функции, такие как fst
или snd
для кортежей с более чем двумя компонентами. Библиотека tuple
в Hackage предоставляет такие функции в модуле Data.Tuple.Select
.
Примените двоичную функцию к кортежу (неуправляемому)
Используйте функцию uncurry
(из Prelude
или Data.Tuple
), чтобы преобразовать двоичную функцию в функцию на кортежах.
uncurry (+) (1, 2) -- computes 3
uncurry map (negate, [1, 2, 3]) -- computes [-1, -2, -3]
uncurry uncurry ((+), (1, 2)) -- computes 3
map (uncurry (+)) [(1, 2), (3, 4), (5, 6)] -- computes [3, 7, 11]
uncurry (curry f) -- computes the same as f
Примените функцию кортежа к двум аргументам (currying)
Используйте функцию curry
(из Prelude
или Data.Tuple
), чтобы преобразовать функцию, которая берет кортежи для функции, которая принимает два аргумента.
curry fst 1 2 -- computes 1
curry snd 1 2 -- computes 2
curry (uncurry f) -- computes the same as f
import Data.Tuple (swap)
curry swap 1 2 -- computes (2, 1)
Компоненты своп-пары
Используйте swap
(из Data.Tuple
) для замены компонентов пары.
import Data.Tuple (swap)
swap (1, 2) -- evaluates to (2, 1)
Или используйте сопоставление шаблонов.
case (1, 2) of (x, y) => (y, x) -- evaluates to (2, 1)
Строгость соответствия кортежа
Шаблон (p1, p2)
строгий в самом внешнем конструкторе кортежа, что может привести к неожиданному поведению строгости . Например, следующее выражение расходится (используя Data.Function.fix
):
fix $ \(x, y) -> (1, 2)
так как совпадение по (x, y)
строго в конструкторе кортежа. Однако следующее выражение, использующее неопровержимый шаблон , оценивает (1, 2)
как и ожидалось:
fix $ \ ~(x, y) -> (1, 2)