Подтвердить что ты не робот

Доступ к определенному элементу в кортеже

Haskell-новичок, сообщающий в. Вопрос заключается в следующем: В Haskell мы имеем fst и snd, которые возвращают первый и второй элементы 2-кортежа. Почему у нас нет простого доступа к i-му элементу из любого кортежа? Прямо сейчас у меня есть 3-кортеж, я хочу прочитать 1-й элемент, и единственный способ выполнить эту задачу - сделать обход шаблонов. Почему это не может быть сделано проще? Или, может быть, есть простой способ?

4b9b3361

Ответ 1

Что мешает языку иметь специальную конструкцию, которую вы хотите, это ее дизайн. Дизайнеры просто не ввели это, потому что это усложняло бы определение языка, которое вполне минималистично. fst и snd являются библиотечными функциями для общего случая пар; вы можете определить все остальные самостоятельно или, лучше, определить типы записей для своих данных, чтобы ваши члены данных имели соответствующие имена.

(Возможно, GHC имеет расширение для этого, но я не сталкивался с этим, проверяйте документы или спрашивайте в списке рассылки.)

Ответ 2

Ознакомьтесь с библиотекой кортежей в хаке. Он имеет перегруженные функции для различных операций с кортежами (до предопределенного размера).

Ответ 3

N-кортежи не являются структурой данных для индексирования с помощью ключа Int, вместо этого вы должны посмотреть на структуры с индексированными смещениями, такие как массивы или пальцы.

Теперь можно было бы написать класс типов для семейства типов кортежей, обеспечивающий операцию index, однако у нас уже есть массивы для что, и там много шаблонов, необходимых для создания кортежей любого типа, легко обеспечить эту операцию. Достигнутая мощность не стоит усилий.

Ответ 4

Почему это нельзя сделать проще? Или, может быть, есть какой-то простой способ?

Это может быть проще, если использовать последнюю альтернативу комплекту линз. Модуль Tuple имеет селекторы для до 9 кортежей элементов, и его легко определить, если необходимо.

> import Control.Lens
> data A = A deriving (Show)
> (1, '2', "3", A) ^. _1
1
> (1, '2', "3", A) ^. _2
'2'
> (1, '2', "3", A) ^. _3
"3"
> (1, '2', "3", A) ^. _4
A

Вы также можете использовать пакет линз для полиморфного обновления элементов, изменения типа при обновлении.

С и без инфиксных операторов:

> (1, '2', "3", A) & _1 .~ "wow"
("wow",'2',"3",A)
 > set _1 "wow" (1, '2', "3", A)
("wow",'2',"3",A)

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


Не только кортежи

Подобный синтаксис работает для Traverables и Foldables, поэтому дерева, Карты, векторы и т.д. Например, если у меня был список кортежей, я могу получить доступ к третьему элементу кортежа на 1 индекс, составляющие element 1, чтобы получить доступ к первому индексу элемента с _3 чтобы получить доступ к третьему элементу кортежа.

[(1,2,3),(4,5,6),(7,8,9)] ^? element 1 . _3
Just 6

Ответ 5

Вопрос о подходе к этому использованию с использованием шаблона haskell был ранее описанным здесь.

Пример его использования:

> $(sel 2 3) ('a','b','c')
'b'
> $(sel 3 4) ('a','b','c','d')
'c'

Отсюда.

Ответ 6

cabal update
cabal install tuple
ghci

λ> import Data.Tuple.Select
λ> sel3 (0, "1", 2) --select the third element

Ответ 7

Никита Волков new "record" library имеет функцию, которая, кажется, делает то, что вы хотите. Искать заголовок "Кортежи - это записи тоже!" на связанной странице.

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