tutorial recorrer listas lista funciones español scala tuples iterable-unpacking

listas - recorrer lista en scala



¿Por qué la sintaxis de Scala para las tuplas es tan inusual? (7)

En matemáticas e informática, una tupla es una lista ordenada de elementos. En la teoría de conjuntos, una n-tupla (ordenada) es una secuencia (o lista ordenada) de n elementos, donde n es un entero positivo.

Entonces, por ejemplo, en Python se accedería al segundo ítem de una tupla a través de t[1] .

En Scala, el acceso solo es posible a través de nombres extraños t._2 .

Entonces la pregunta es, ¿por qué no puedo acceder a los datos en tuplas como Secuencia o Lista si es por definición? ¿Hay algún tipo de idea o aún no se ha inspeccionado?


Además de los beneficios que Jean-Philippe Pellet ya mencionó, esta notación también es muy común en matemáticas (ver http://en.wikipedia.org/wiki/Tuple ). Muchos profesores añaden índices a variables de tupla si quieren referirse a los elementos de una tupla. Y la notación común (LaTeX) para escribir "con índice n " (que se refiere al enésimo elemento de la tupla) es _n . Así que, en realidad, lo encuentro muy intuitivo.


Con el acceso al índice normal, se puede usar cualquier expresión, y se requeriría un esfuerzo serio para verificar en tiempo de compilación si el resultado de la expresión del índice está garantizado dentro del rango. Conviértalo en un atributo, y un error en tiempo de compilación para (1, 2)._3 sigue "gratis". Cosas como permitir únicamente las constantes enteras dentro del acceso a los elementos en las tuplas sería un caso muy especial (feo e innecesario, algunos dirían ridículo) y otra vez algo de trabajo para implementar en el compilador.

Python, por ejemplo, puede salirse con la suya porque no (no podría) verificar (en tiempo de compilación, eso es) si el índice está dentro del rango de todos modos.


Creo que el siguiente extracto de "Programación en Scala: una guía completa paso a paso" (Martin Odersky, Lex Spoon y Bill Venners) aborda directamente sus dos preguntas:

Accediendo a los elementos de una tupla

Es posible que se pregunte por qué no puede acceder a los elementos de una tupla como los elementos de una lista, por ejemplo, con "par (0)". El motivo es que el método de aplicación de una lista siempre devuelve el mismo tipo, pero cada elemento de una tupla puede ser de un tipo diferente: _1 puede tener un tipo de resultado, _2 otro, y así sucesivamente. Estos números _N están basados ​​en uno, en lugar de basados ​​en cero, porque comenzar con 1 es una tradición establecida por otros idiomas con tuplas estáticamente tipadas, como Haskell y ML.

Las tuplas de Scala reciben muy poco tratamiento preferencial en lo que se refiere a la sintaxis del lenguaje, aparte de las expresiones ''('' a1, ..., an '')'' que el compilador trata como un alias para scala.Tuplen ( a1, ... , an ) instanciación de clase. De lo contrario, las tuplas se comportan como cualquier otro objeto de Scala, de hecho están escritas en Scala como clases de caso que van desde Tuple2 a Tuple22 . Tuple2 y Tuple3 también se conocen bajo los alias de Pair y Triple, respectivamente:

val a = Pair (1,"two") // same as Tuple2 (1,"two") or (1,"two") val b = Triple (1,"two",3.0) // same as Tuple3 (1,"two",3.0) or (1,"two",3.0)


Creo que es para verificar el tipo. Como dice delnan, si tiene una tupla t y un índice e (una expresión arbitraria), t(e) le daría al compilador información sobre qué elemento se está accediendo (o incluso si es un elemento válido para una tupla de ese tamaño) ) Cuando accede a elementos por nombre de campo ( _2 es un identificador válido, no es una sintaxis especial), el compilador sabe a qué campo está accediendo y qué tipo tiene. Los lenguajes como Python en realidad no tienen tipos, por lo que no es necesario para ellos.


Scala conoce la aridad de las tuplas y, por lo tanto, puede proporcionar _1 como _1 , _2 , etc., y producir un error en tiempo de compilación si selecciona _3 en un par, por ejemplo. Además, el tipo de esos campos es exactamente lo que el tipo utilizado como parámetro para Tuple (por ejemplo, _3 en un Tuple3[Int, Double, Float] devolverá un Float ).

Si desea acceder al enésimo elemento, puede escribir tuple.productElement(n) , pero el tipo de devolución de esto solo puede ser Any , por lo que pierde la información del tipo.


Una gran diferencia entre List , Seq o cualquier colección y tupla es que en tupla cada elemento tiene su propio tipo, donde en List todos los elementos tienen el mismo tipo.

Y como consecuencia, en Scala encontrarás clases como Tuple2[T1, T2] o Tuple3[T1, T2, T3] , por lo que para cada elemento también tienes un parámetro de tipo. Las colecciones aceptan solo 1 parámetro de tipo: List[T] . Sintaxis como ("Test", 123, new Date) es solo azúcar sintáctica para Tuple3[String, Int, Date] . Y _1 , _2 , etc. son solo campos en tupla que devuelven el elemento correspondiente.


Usted puede lograr fácilmente eso con shapeless :

import shapeless.syntax.std.tuple._ val t = ("a", 2, true, 0.0) val s = t(0) // String at compile time val i = t(1) // Int at compile time // etc

Una gran cantidad de métodos disponibles para la colección estándar también están disponibles para tuplas de esta manera ( head , tail , init , last , ++ y ::: para concatenación, +: y :+ para agregar elementos, take , drop , reverse , zip , unzip , length , toList , toArray , to[Collection] , ...)