_
is a wildcard. It says make sure there is a value here but I don't want to bind it to any variable. :
is the constructor for a list. On the left is one value and the right is the rest of the list. The rest of the list can be empty. So if you do something like this:
(x:xs)
x is the first element of the list and xs can be an empty list or it can be an infinite amount of elements.
(x:y:xs)
Would only match lists with at least 2 elements. The @
is the at pattern. It binds the entirety of the right expression to the left variable.
m@(Just _)
Here m
would have the type Maybe a
. The _
is just used because Just
is of type a -> Maybe a
and we need to have a placeholder for its argument. So m
binds to the whole value of (Just _). In your example.
s@(_:_)
s
is the whole list. And (_:_)
specifies that the list must have at least one element or the match will fail. If we wrote:
s@(x:xs)
x
would be the first element and xs
would be the tail of the list. s == x:xs
would return True
. But since we don't need the head or the tail we simply use _
.