This is a type alias [Haskell wiki]. It is used to often give a name to more complicated types.
For example if you define a function:
sum2 :: Pair Int -> Int
sum2 (x, y) = x + y
then behind the curtains, this is thus resolved to:
sum2 :: (Int, Int) -> Int
sum2 (x, y) = x + y
Type aliases are often used to
- to give a special structure a more convenient name;
- to shorten complicated types; and
- to make it easy to switch from type.
For example a String is defined as:
type String = [Char]
A String is thus simply a list of Characters. But a signature with String focuses on the fact that it works with textual data.
Type aliases are often used to abstract away complexity of a type. For example we can define a type Operator:
type Operator a = a -> a -> a
This is thus an alias for a function that maps two parameters of type a to a value of type a. This is interesting if we later want to create functions that work with this operator. For example:
maxOperator :: Ord a => Operator a -> Operator a -> Operator a
maxOperator f g x y = max (f x y) (g x y)
This is more likely more readable than:
maxOperator :: Ord a => (a -> a -> a) -> (a -> a -> a) -> (a -> a -> a)
maxOperator f g x y = max (f x y) (g x y)
and it definitely is more readable if we would later use Operator (Operator a), which thus resolves to (a -> a -> a) -> (a -> a -> a) -> a -> a -> a.
Finally types are sometimes used if it is not yet completely clear what type you will use. If you are for example implementing a package and you have not yet decided to work with Floats or Doubles, you can define a type alias:
type Scalar = Float
If you then later change your mind, you can rewrite it to type Scalar = Double, and all places where you used Scalar will now resolve to Double.