Pattern matching a non-empty tail of a list

The following does not compile. Is there a way to pattern match a list that has a head and a non-empty tail?

firstNumber : [Int] -> Text
firstNumber [] = "Empty list!"
firstNumber [x] = "The *only* number is " <> (show x)
firstNumber x::xs = "The *first* number is " <> (show x)
firstNumber (x::y::xs) = "The *first* number is " <> (show x) <> " and second is " <> show y

Interesting, @Leonid_Rozenberg. You are right. The pattern (x::y::xs) can be used to identify lists with at least two items.

import DA.Assert

firstNumber : [Int] -> Text
firstNumber (x::y::xs) = "The *first* number is " <> (show x)
firstNumber [x] = "The *only* number is " <> (show x)
firstNumber [] = "Empty list!"

testing = script do
  "Empty list!" === firstNumber []
  "The *only* number is 1" === firstNumber [1]
  "The *first* number is 1" === firstNumber [1, 2]
  "The *first* number is 1" === firstNumber [1, 2, 3, 4]

I suppose I could use (x::xs) instead of (x::y::xs) if the order of the matching filters out single-element lists first:

import DA.Assert

firstNumber : [Int] -> Text
firstNumber [] = "Empty list!"
firstNumber [x] = "The *only* number is " <> (show x)
firstNumber (x::xs) = "The *first* number is " <> (show x)

testing = script do
  "Empty list!" === firstNumber []
  "The *only* number is 1" === firstNumber [1]
  "The *first* number is 1" === firstNumber [1, 2]
  "The *first* number is 1" === firstNumber [1, 2, 3, 4]

But, I see (x::y::xs) captures the intent without requiring the context of the surrounding pattern matching statements. Nice!

Being able to write precise pattern matches to express logic (ex, a list with at least 2 elements) is one of the unacknowledged strengths of functional programming languages.