Как получить n-й элемент из 10-кортежей в Haskell?

Мне нужно получить n-й элемент в кортеже Haskell. И кортежи таковы: (3,5, "Строка1", "строка2", "String3", "String4", "String5", "String6", "String7", "String8", "String9", "String10" ). Можете ли вы дать мне представление, чтобы я мог решить эту проблему? Спасибо.

Ответы

Ответ 1

Поскольку вы можете или не можете знать, что fst и snd работают только для 2-элементных кортежей, т.е.

fst' (a,b) = a

Вы должны написать себе, насколько я знаю

get5th (_,_,_,_,a,_,_,_,_,_) = a

Как вы можете видеть, вы можете определить свой собственный тип.

Ответ 2

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

let (_, _, _, _, _, _, _, _, _, x, _, _) = tuple in x

Однако, скорее всего, вы не хотите этого делать. Если вы пытаетесь получить n-е значение из кортежа, вы почти наверняка используете неправильный тип. В Haskell кортежи разной длины являются разными типами - они принципиально несовместимы. Точно так же, как Int и String отличаются, (Int, Int) и (Int, Int, Int) также совершенно разные.

Если вам нужен тип данных, в котором вы можете получить n-й элемент, вам нужен список: что-то вроде [String]. Со списками вы можете использовать оператор !! для индексирования (который начинается с 0), поэтому вы можете просто сделать:

myList !! 9

чтобы получить 10-й элемент.

Учитывая ваш пример, я подозреваю, что вам нужен тип типа (Int, Int, [String]), а не гигантский кортеж. Это позволит вам иметь два числа и любое количество строк; вы можете получить строки по индексу с помощью оператора !!, как указано выше.

Ответ 4

Если вам нужно сделать это только один раз за кортеж, и вам нужны все элементы сразу, вы можете просто использовать

let (x, y, s1, s2, s3, s4, s5, s6, s7, s8) = someTuple
in ...

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

Ответ 5

Я видел ваш вопрос, когда искал решение по той же проблеме. Я прочитал "!!" оператор - плохое решение. Я подумал о решении:

Например, если у вас есть три элемента для каждого кортежа в вашем списке, вы можете сделать это:

nTuple :: [(a, a, a)] -> Integer -> Integer -> [a]
nTuple list group position = [ fst x | x <- (concat [ fst x | x <- (zip [(zip[t1, t2, t3][0..]) | (t1, t2, t3) <- list ] [0..]) , snd(x) == group ]) , snd(x) == position]

Теперь несколько тестовых случаев:

*Main> nTuple [("l","m","n"),("o","p","q"),("r","s","t")] 2 1
["s"]

*Main> nTuple [("l","m","n"),("o","p","q"),("r","s","t")] 0 2
["n"]

*Main> nTuple [("l","m","n"),("o","p","q"),("r","s","t")] 100 2
[]

*Main> nTuple [("l","m","n"),("o","p","q"),("r","s","t")] 2 100
[]

Объяснение шаг за шагом указанной функции:

1.Split элементы и поместите индекс:

[ zip[t1,t2,t3][0..] | (t1,t2,t3) <- [("l","m","n"),("o","p","q"),("r","s","t")]]

result: [[("l",0),("m",1),("n",2)],[("o",0),("p",1),("q",2)],[("r",0),("s",1),("t",2)]]

2. Для каждого списка введите индекс. Теперь у нас есть группы и позиции внутри каждой группы.

zip [[("l",0),("m",1),("n",2)],[("o",0),("p",1),("q",2)],[("r",0),("s",1),("t",2)]] [0..]

result: [([("l",0),("m",1),("n",2)],0),([("o",0),("p",1),("q",2)],1),([("r",0),("s",1),("t",2)],2)]

3. Мы можем выбрать группу. Например, группа номер 1 (первая группа - 0) с "snd (x) == 1"

[ fst x | x <- [([("l",0),("m",1),("n",2)],0),([("o",0),("p",1),("q",2)],1),([("r",0),("s",1),("t",2)],2)] , snd(x) == 1 ]

result: [[("o",0),("p",1),("q",2)]]

4. У нас есть список списков. Whe объединяет кортежи в одном списке кортежей

concat [[("o",0),("p",1),("q",2)]]

result: [("o",0),("p",1),("q",2)]

5. Наконец, мы получим элемент по индексу. В этом примере мы получаем второй элемент (первый элемент - это позиция "0" )

[ fst x | x <- [("o",0),("p",1),("q",2)] , snd(x) == 2]

result ["q"]