Yes, it’s just syntactic sugar, with @ read aloud as “as”. ps@(p:pt) gives you names for
- the list:
ps - the list’s head :
p - the list’s tail:
pt
Without the @, you’d have to choose between (1) or (2):(3).
This syntax actually works for any constructor; if you have data Tree a = Tree a [Tree a], then t@(Tree _ kids) gives you access to both the tree and its children.