Types and Typeclasses
As previously mentioned, Haskell has a static type system. This leads to safer code. If you have an expression that tries to divide a boolean with some type of number, it won't even compile.
Haskell also has type inference. Unlike in other languages such as Java or Pascal, we don't have to declare a value as a certain type in Haskell. If we write a number, it will infer that we are dealing with a value of that type.
Like other programming languages, common types in Haskell include:
8 => Int
Factorial 50 => Integer
The Integer type represents very large numbers2.5 => Float
4.0 => Double
"a" => Char
True => Bool
In ghci, we can evaluate a value's type by printing :t
followed by the value.
If you want to give your function a type declaration but are unsure as what it should be, you can always write it without the declaration and check its return
type with :t
.
If we were to evaluate the type of the head
function, this is what we would return:
ghci> :t head
head :: [a] -> a
Type a
is what is called a type variable. That means that a
can be of any type. This allows us to write very general functions that don't use any specific behavior of the types in them. Functions that have type variables are
called polymorphic functions.
A typeclass is a sort of interface that defines some behavior. All types are a part of a typeclass.
What is the type signature of the ==
function?
ghci> :t (==)
(==) :: (Eq a) => a-> a -> Bool
Note: The ==
operator is a function. All other logical operators are
functions as well.
In the above evaluation, we see a new symbol, =>
. This symbol is a class constraint. We can see that the equality function takes any two values that are of the same type and returns a Bool
. Those two values must be a member of
the Eq
class (the class constraint).
Some of the common typeclasses:
Eq => For equality testing
Ord => For types that have an ordering (think >,<,>=,<=)
Show => Members can be presented as strings.
Read => Takes a string and returns a type of which is a member of Read
Enum => Sequentially ordered types
Bounded => Members have an upper and lower bound
Num => A numeric typeclass
Integral => Includes all numbers, including real numbers and integral numbers
- `Floating => Includes only floating point numbers