Types and type signatures
| Basic types | |
| Lists, tuples, functions | |
| Read a signature | |
| Int or Integer |
Basic types
A type names a set of values. The ones you meet on day one are small and precise:
Int -- 64-bit signed integer on modern platforms
Integer -- arbitrary precision integer
Double -- 64-bit floating point
Bool -- True or False
Char -- one Unicode code point
String -- [Char], a list of characters
Type names start with a capital letter, values with a lower case letter. That convention is enforced by the parser, not by taste.
Lists, tuples, functions
Compound types are written with brackets and arrows. A list holds any number of values of one type; a tuple holds a fixed number of values of possibly different types:
[Int] -- list of integers
[(String, Int)] -- list of pairs
(Int, Bool, Char) -- a triple
Int -> Int -- function from Int to Int
Int -> Int -> Int -- two arguments
The last line has no separate syntax for several arguments: it is a function that takes an Int and returns a function. Lesson 8 shows why that distinction pays off.
Read a signature
Everything left of the last arrow is an argument, everything right of it is the result. The name before the double colon is the value being described:
repeatN :: Int -> String -> String
repeatN n s = concat (replicate n s)
-- repeatN 3 "ab" == "ababab"
Signatures are optional, because GHC infers them, but a top-level function without one is a gift to future confusion. Write the signature first and let the compiler tell you when the body disagrees.
Int or Integer
Int wraps a machine word and can overflow silently. Integer grows as needed and is the safe default for arithmetic that may exceed 64 bits:
big :: Integer
big = product [1..30] -- 265252859812191058636308480000000
The same expression typed as Int still fits
here, but at 21 factorial it does not. Choose
Integer when the size is unknown and
Int when it is a counter or an index.
Next:
Functions and application
Article author: Arthur Isaev