A type is a collection of related values.
Excerpt From: Graham Hutton. “Programming in Haskell” (2nd ed.).
This means that the set-theoretic definition of the type Bool
could be thought of as Bool = {True, False}
and the type Bool -> Bool
would be Bool->Bool = {f: Bool -> Bool}
.
Haskell uses the notation e :: T
to say that e
is a value in the type T
(that is, e
has type T
).
Every expression must have a type. Types are calculated prior to evaluating an expression via type inference. We get type errors when the inferred type is not the same as the explicit type.
Type | Values |
---|---|
Bool |
Logical values |
Char |
Single characters |
String |
A list of characters |
Int |
Fixed-precision integers |
Integer |
Arbitrary-precision integers |
Float |
Single-precision floating-point numbers |
Double |
Double-precision floating-point numbers |
A list is a sequence of elements of the same type, with the elements being enclosed in square parentheses and separated by commas. We write
[T]
for the type of all lists whose elements have typeT
…Excerpt From: Graham Hutton. “Programming in Haskell” (2nd ed.).
The type of list says nothing of its length (which may be infinite, because Haskell provides for lazy evaluation).
A tuple is a finite sequence of components of possibly different types, with the components being enclosed in round parentheses and separated by commas.
Excerpt From: Graham Hutton. “Programming in Haskell” (2nd ed.).
The number of components of a tuple is called its arity. The arity of a tuple is zero or at least two (it must however, be finite). A tuple with arity one is not permitted because, as Graham notes, it would “conflict with the use of parentheses to make [arithmetic] evaluation order explicit.”
A function is a mapping from arguments of one type to results of another type.
Excerpt From: Graham Hutton. “Programming in Haskell” (2nd ed.).
Functions in Haskell are curried – that is, functions can return functions that take additional arguments.
As well as being interesting in their own right, curried functions are also more flexible than functions on tuples, because useful functions can often be made by partially applying a curried function with less than its full complement of arguments.
Excerpt From: Graham Hutton. “Programming in Haskell” (2nd ed.).
The arrow operator is right associative, which allows for excess parentheses when using curried functions. Graham notes that Int -> Int -> Int -> Int
and Int -> (Int -> (Int -> Int))
are equivalent.
Graham also points out that, as a result, function application is left-associative: must x y z
and ((must x) y) z
are equivalent.
Unless tupling is explicitly required, all functions in Haskell with multiple arguments are normally defined as curried functions, and the two conventions above are used to reduce the number of parentheses that are required.
Excerpt From: Graham Hutton. “Programming in Haskell” (2nd ed.).
Polymorphic types are ones that can take any type as an argument. The length
function is an example of a polymorphic type. It has the type length :: [a] -> Int
.
A class constraint serves to restrict the application of a function to a certain instance of a type.
Class constraints are written in the form
C a
, whereC
is the name of a class anda
is a type variable. For example, the type of the addition operator+
is as follows:
(+) :: Num a => a -> a -> a
That is, for any type a that is an instance of the class
Num
of numeric types, the function(+)
has typea -> a -> a
.Excerpt From: Graham Hutton. “Programming in Haskell” (2nd ed.).
A type that includes class constraints is called overloaded.
Numbers themselves are also overloaded. For example,
3 :: Num a => a
means that for any numeric typea
, the value 3 has typea
. In this manner, the value 3 could be an integer, a floating-point number, or more generally a value of any numeric type, depending on the context in which it is used.Excerpt From: Graham Hutton. “Programming in Haskell” (2nd ed.).
Recall that a type is a collection of related values. Building upon this notion, a class is a collection of types that support certain overloaded operations called methods.
Excerpt From: Graham Hutton. “Programming in Haskell” (2nd ed.).
This class contains types whose values can be compared for equality and inequality using the following two methods:
(==) :: a -> a -> Bool
(/=) :: a -> a -> Bool
All the basic types,
Bool
,Char
,String
,Int
,Integer
,Float
, andDouble
, are instances of theEq
class, as are list and tuple types, provided that their element and component types are instances.Excerpt From: Graham Hutton. “Programming in Haskell” (2nd ed.).
Function types are not typically instances of Eq
because it is not usually feasible to compare two functions for equality.
This class contains types that are instances of the equality class
Eq
, but in addition whose values are totally (linearly) ordered, and as such can be compared and processed using the following six methods:
(<) :: a -> a -> Bool
(<=) :: a -> a -> Bool
(>) :: a -> a -> Bool
(>=) :: a -> a -> Bool
min :: a -> a -> a
max :: a -> a -> a
All the basic types,
Bool
,Char
,String
,Int
,Integer
,Float
, andDouble
, are instances of theOrd
class, as are list and tuple types, provided that their element and component types are instances.Excerpt From: Graham Hutton. “Programming in Haskell” (2nd ed.).
String
s, lists, and tuples are ordered lexicographically.
These class is made of types that can be converted to a String
. The basic list, tuple, and types we know are all instances of Show
.
This class complements Show
in that it contains types which chan be converted from a String
to some other type. The basic list, tuple, and types we know are all instances of Show
.
Read
can usually infer the type that the String
should be converted to, but we can make the type inference explicit by using :: T
. As an example:
read "[1,2,3]" :: [Int]
tells GHC to turn the string into a list of Int
instead of keeping it as a String
.
This class contains types whose values are numeric, and as such can be processed using the following six methods:
(+) :: a -> a -> a
(-) :: a -> a -> a
(*) :: a -> a -> a
negate :: a -> a -> Bool
abs :: a -> a
signum :: a -> a
The basic types
Int
,Integer
,Float
, andDouble
are instances of theNum
class.Excerpt From: Graham Hutton. “Programming in Haskell” (2nd ed.).
This class contains types whose values are instances of the numeric class
Num
, but in addition whose values are integers, and as such support the methods of integer division and integer remainder:
div :: a -> a -> a
mod :: a -> a -> a
The basic types
Int
andInteger
, are instances of theIntegral
class.Excerpt From: Graham Hutton. “Programming in Haskell” (2nd ed.).
This class contains types whose values are instances of the numeric class
Num
, but in addition whose values are non-integral, and as such support the methods of fractional division and fractional reciprocation:
(/) :: a -> a -> a
recip :: a -> a -> a
The basic types
Float
andDouble
are instances.Excerpt From: Graham Hutton. “Programming in Haskell” (2nd ed.).