last :: [a] -> a is the Haskell98 syntax for the System F type
last :: ∀ a. [a] -> a
The ∀ a can be understood as a kind of type-level lambda binding, i.e. before the actual value level list parameter the function accepts a type-level argument telling what the type of elements contained in the list. This universal quantification makes the function parametrically polymorphic.
Normally, the type variables are automatically inserted by the type checker. In newer GHC Haskell, you can also explicitly apply them:
Prelude> :set -XTypeApplications
Prelude> :t last @Int
last @Int :: [Int] -> Int
Prelude> last @Double [5,6,7]
7.0
negate is also parametrically polymorphic, but unlike last it does not work truely “for all” types, but only for those that have a Num instance (which both Int and Double do, but not e.g. Char). In other words, it accepts not only an extra argument specifying the type, but also a proof that it does indeed have a Num instance. That too will be inserted automatically by the compiler.
negate :: ∀ a. Num a => a -> a
Prelude> :t negate @Int
negate @Int :: Int -> Int
Prelude> :t negate @Char
<interactive>:1:1: error:
No instance for (Num Char) arising from a use of ‘negate’