Was bedeutet das Symbol "@" in Bezug auf Listen in Haskell?

127

Ich bin auf einen Haskell-Code gestoßen, der so aussieht:

ps@(p:pt)

Was bedeutet das @Symbol in diesem Zusammenhang? Ich kann anscheinend keine Informationen bei Google finden (es ist leider schwierig, bei Google nach Symbolen zu suchen), und ich kann die Funktion in der Prelude-Dokumentation nicht finden, daher stelle ich mir vor, dass es sich stattdessen um eine Art syntaktischen Zucker handeln muss.

Mipadi
quelle
14
Versuchen Sie nicht, nach diesem bestimmten Symbol zu suchen. Suchen Sie nach der Haskell-Syntax im Allgemeinen und finden Sie dann das Symbol in dieser allgemeinen Diskussion. Beispiel: Das beste Google-Ergebnis für "Haskell-Syntax": cs.utep.edu/cheon/cs3360/pages/haskell-syntax.html . Das zweite Auftreten @auf dieser Seite erklärt es.
Rob Kennedy
1
Gut, dass ich genau erwähnt habe, wie ich diese URL gefunden habe, @Iter. Jeder kann den Vorgang heute wiederholen und die Antwort auf jeder Seite finden, die er findet.
Rob Kennedy

Antworten:

179

Ja, es ist nur syntaktischer Zucker, der @als "wie" vorgelesen wird. ps@(p:pt)gibt Ihnen Namen für

  1. Die Liste: ps
  2. der Kopf der Liste: p
  3. der Schwanz der Liste: pt

Ohne das @müssten Sie zwischen (1) oder (2) wählen :( 3).

Diese Syntax funktioniert tatsächlich für jeden Konstruktor. wenn Sie haben data Tree a = Tree a [Tree a], dann t@(Tree _ kids)haben Sie Zugriff sowohl auf den Baum und seine Kinder.

Nathan Shively-Sanders
quelle
3
Kennen Sie den Namen für diese Syntax?
Danza
7
Es wird ein "as-pattern" genannt
Adamo
41

Das @Symbol wird verwendet, um einem Parameter einen Namen zu geben und diesen Parameter mit einem Muster abzugleichen, das dem folgt @. Es ist nicht listenspezifisch und kann auch mit anderen Datenstrukturen verwendet werden.

Dies ist nützlich, wenn Sie einen Parameter in seine Teile "zerlegen" möchten, während Sie den Parameter als Ganzes noch irgendwo in Ihrer Funktion benötigen. Ein Beispiel, in dem dies der Fall ist, ist die tailsFunktion aus der Standardbibliothek:

tails                   :: [a] -> [[a]]
tails []                =  [[]]
tails xxs@(_:xs)        =  xxs : tails xs
etw
quelle
21

Ich möchte hinzufügen, dass dies @auf allen Ebenen funktioniert, was bedeutet, dass Sie dies tun können:

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

Welches wird dann dies produzieren: ((Just 1, Just 2), Just 1, 1, 2)

Im Grunde ist es eine Möglichkeit für Sie, ein Muster an einen Wert zu binden. Dies bedeutet auch, dass es mit jeder Art von Muster funktioniert , nicht nur mit Listen, wie oben gezeigt. Dies ist sehr nützlich zu wissen, da Sie es in vielen weiteren Fällen verwenden können.

In diesem Fall aist das Ganze Maybe Tuple, bist nur der erste Justim Tupel und cund dsind die Werte, die im ersten bzw. zweiten Justim Tupel enthalten sind

Elektrischer Kaffee
quelle
9

Um das zu ergänzen, was die anderen Leute gesagt haben, werden sie als Muster bezeichnet (in ML verwendet die Syntax das Schlüsselwort "as") und werden im Abschnitt des Haskell-Berichts über Muster beschrieben .

newacct
quelle