X
使用列表,我可以使用 operator获取索引的元素!!
。
例如:
Prelude> let lista = [2,4..20]
Prelude> lista
[2,4,6,8,10,12,14,16,18,20]
Prelude> lista !! 0
2
Prelude> lista !! 5
12
现在我正在学习 Haskell 中的元组,如果我尝试以相同的方式通过索引访问元素,我会收到错误消息:
Prelude> let tupla = (1, "Hola", 'Z')
Prelude> tupla
(1,"Hola",'Z')
Prelude> tupla !! 1
<interactive>:9:1:
Couldn't match expected type `[a0]'
with actual type `(Integer, [Char], Char)'
In the first argument of `(!!)', namely `tupla'
In the expression: tupla !! 1
In an equation for `it': it = tupla !! 1
通过索引访问元组元素的正确方法是什么?
元组不是由整数索引的数据结构。
要访问一对中的元素,您可以使用
fst
和函数snd
。例如,如果要访问元组的第三个元素,可以使用模式匹配:或者您也可以使用tuple 包
select
中的那个。但是,不推荐使用非常大的元组。非常大的元组通常表明应该使用另一种类型。
为了补充 Nicolocodev 的答案,需要注意的是 Haskell 中的列表和元组之间的以下重要区别(通常是静态类型语言):
这对您的问题有重要影响。让我们看一下从列表中提取元素的函数的类型:
我们可以看到类型变量
a
在函数类型中出现了两次:[a]
;但是现在让我们试着想象一下:通过索引获取元组元素的函数的类型是什么?我们可以从概述类型开始,使用
_tupla
和_elemento
作为我们将尝试填充的类型的空白:我们面临的第一个问题是基本 Haskell 中没有类型在其值中包含各种大小的元组。即二、三、四等元组。元素是不同的类型,所以我们不能编写一个接受任何大小的元组作为参数的函数。对于每种大小的元组,我们需要一个单独的函数:
现在是第二个问题:我们用什么类型填充我标记的空白
_elemento
?困难在于,根据我们作为参数给出的索引,元组的该元素中的值的类型是不同的。再说一次,我们不能从字面上写出这样的函数;我们需要对这个问题做出一些改变。例如,我们可以执行以下操作,引入 sum 类型(“sum types”),它们负责表示结果是具有异构类型的情况的总和这一事实:或者我们可以要求元组的所有元素都是同一类型:
现在我们的函数并不适用于所有的元组——只有那些元素是同质类型的。但是通过这样做,我们消除了元组和列表之间的一半差异——唯一剩下的区别是不同长度的列表仍然是相同类型的值。请记住,这就是我们引入 的原因
elementoDeTupla2
,elementoDeTupla3
并且elementoDeTupla4
作为单独的函数;所以现在,为了消除重复,我们在开始的地方结束,使用列表:这给我们带来了您问题的答案:如果您需要按索引获取元素,这表明您需要使用列表,而不是元组。(虽然实际上在这种情况下使用通常会更好
Vector
,它允许在恒定时间内按索引访问。)