Доступ к определенному элементу в кортеже - PullRequest
33 голосов
/ 01 мая 2011

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

Ответы [ 7 ]

29 голосов
/ 01 мая 2011

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

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

21 голосов
/ 01 мая 2011

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

13 голосов
/ 01 мая 2011

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

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

8 голосов
/ 26 мая 2014

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

Это может быть проще, если использовать последнюю альтернативу - пакет lens .Модуль 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

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

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

> (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, поэтому Trees, Maps, Векторы и т. Д. Например, если у меня есть список кортежей, я могу получить доступ к третьему элементу кортежа по индексу 1, составив element 1 для доступа к первому элементу индекса с помощью _3 для доступа к третьему элементу кортежа.

[(1,2,3),(4,5,6),(7,8,9)] ^? element 1 . _3
Just 6
4 голосов
/ 01 мая 2011

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

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

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

Отздесь .

2 голосов
/ 14 апреля 2016
cabal update
cabal install tuple
ghci

λ> import Data.Tuple.Select
λ> sel3 (0, "1", 2) --select the third element
1 голос
/ 23 июля 2015

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

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

...