¿Qué significa el símbolo "@" en referencia a las listas en Haskell?

128

Me he encontrado con un código de Haskell que se ve así:

ps@(p:pt)

¿Qué significa el @símbolo en este contexto? Parece que no puedo encontrar ninguna información en Google (desafortunadamente es difícil buscar símbolos en Google), y no puedo encontrar la función en la documentación del Preludio, así que imagino que debe ser algún tipo de azúcar sintáctica.

mipadi
fuente
14
No intentes buscar ese símbolo específico. Busque la sintaxis de Haskell en general y luego encuentre el símbolo en esa discusión general. Por ejemplo, el resultado principal de Google para la "sintaxis de Haskell": cs.utep.edu/cheon/cs3360/pages/haskell-syntax.html . La segunda aparición de @en esa página lo explica.
Rob Kennedy el
1
Lo bueno es que mencioné exactamente cómo encontré esa URL, @Iter. Cualquiera puede repetir el proceso hoy y encontrar la respuesta en cualquier página que encuentren.
Rob Kennedy

Respuestas:

179

Sí, es solo azúcar sintáctico, con @lectura en voz alta como "como". ps@(p:pt)te da nombres para

  1. la lista: ps
  2. la cabeza de la lista: p
  3. la cola de la lista: pt

Sin el @, deberías elegir entre (1) o (2) :( 3).

Esta sintaxis realmente funciona para cualquier constructor; si es así data Tree a = Tree a [Tree a], le t@(Tree _ kids)da acceso tanto al árbol como a sus hijos.

Nathan Shively-Sanders
fuente
3
¿Conoces el nombre de esta sintaxis?
danza
77
Se llama "as-pattern"
adamo
41

El @símbolo se usa para dar un nombre a un parámetro y hacer coincidir ese parámetro con un patrón que sigue al @. No es específico de las listas y también se puede usar con otras estructuras de datos.

Esto es útil si desea "descomponer" un parámetro en sus partes mientras necesita el parámetro como un todo en algún lugar de su función. Un ejemplo donde este es el caso es la tailsfunción de la biblioteca estándar:

tails                   :: [a] -> [[a]]
tails []                =  [[]]
tails xxs@(_:xs)        =  xxs : tails xs
algo
fuente
21

Quiero agregar que @funciona en todos los niveles, lo que significa que puede hacer esto:

let a @ (b @ (Just c), Just d) = (Just 1, Just 2) in (a, b, c, d)

Lo que luego producirá esto: ((Just 1, Just 2), Just 1, 1, 2)

Básicamente, es una forma de vincular un patrón a un valor. Esto también significa que funciona con cualquier tipo de patrón, no solo listas, como se demostró anteriormente. Es muy útil saberlo, ya que significa que puede usarlo en muchos más casos.

En este caso, aes el todo Maybe Tuple, bes solo el primero Justen la tupla, cy dson los valores contenidos en el primero y el segundo Justen la tupla respectivamente

Cafe electrico
fuente
9

Para agregar a lo que las otras personas han dicho, se llaman as-patterns (en ML, la sintaxis usa la palabra clave "as"), y se describen en la sección del Informe Haskell sobre patrones .

newacct
fuente