[Progress on types, chapter 3. Bryan O'Sullivan **20070711071440] { adddir ./examples/ch03 hunk ./en/Makefile 14 + $(wildcard ../examples/ch03/*.ghci) \ hunk ./en/Makefile 119 -$(tools:%=../tools/bin/%): ../tools/.setup-config +$(tools:%=../tools/bin/%): ../tools/.setup-config ../tools/*.hs hunk ./en/ch02-starting.xml 626 - + hunk ./en/ch03-funcs-types.xml 5 + + + Haskell's type system + + Haskell has a strong, static type system with + inference. For a short sentence, this one has a lot + for us to pore over. Because Haskell is quite different from + mainstream programming languages in how it treats types, let's + not assume anything as we talk about types. + + Every value and expression in Haskell has a + type. The type of a value indicates that + it shares certain properties with other values that have the + same type. (You'll see us refer to a value having the + type X, or being of type + X. The two phrases mean the same thing.) + All values that have the type Integer have the + ability to be added to other values of type + Integer, and so on. + + Haskell has a strong type system, in which + every expression and value has exactly one type. Where many + other programming languages have rules under which they will + automatically convert values from one type to another for us, + Haskell does not second guess our intentions. This is another + aspect of its notion of strong typing. + + + Conversations about type systems can lead to many a + misunderstanding among programmers. Some people say that C + has a strong type system; others claim that Python does. + Haskell programmers think strong typing is still something + else. + + Since there's no universally agreed upon meaning for the + phrase strong types, it's best not to assume + that someone else shares the same notion of it as you do. (We + also suggest that putting forth one definition as better than + another doesn't often lead to enlightened discussion.) + + + Having a static type system means that the + compiler knows the type of every value and expression at compile + time, before any code is ever executed. A Haskell compiler or + interpreter will detect when we try to use types inconsistently + in our code, and reject the code with an error message. + + &ch03.basics.ghci:error; + + Static typing also means that type errors can't occur when a + program is running. + + Finally, type inference means what it says: + the compiler can automatically figure out the types of most + values for us, so that we don't have to explicitly label + them. + + We've already briefly seen Haskell's notation for types in + . We write expression + :: MyType to say that + expression has the type MyType. + + + + Haskell's standard types + + We've already encountered a few types in . Haskell has a number of + built-in types that we'll use all the time. We can categorise + these into basic types and + compound types that we build from basic + types. + + + Basic types + + A basic type is simply one that isn't + constructed from any simpler types. + + + + The Char type represents a character. + The values of Char are drawn from the Unicode + character set. + + + The Bool type represents a value in + Boolean logic. The possible values of Bool + are True and False. + + + The Int type represents a signed, + fixed-width integer. The exact range of values + represented by Int depends on the system's + longest native integer: on a 32-bit + machine, an Int is usually 32 bits wide, + while on a 64-bit machine, it is usually 64 bits + wide. + + + The Integer type represents a signed + integer of arbitrary width. Integer values + are not used as often as Ints, because + they're a lot more expensive to work with. + + + The Double type is the usual type used to + represent floating point numbers. It is typically 64 bits + wide. + + + + + + Boolean values and algebraic data types + + The Bool type that we introduced above is the + simplest example of a category called an algebraic + data type. An algebraic data type has a fixed + (and usually small) set of possible values, each of which is + identified by a name. Each name is called a + constructor. + + In the case of Bool, the type has two + constructors, True and False. We + call them constructors because they're what we use to create + values. When we write False, Haskell will + construct that value. + + We'll have much more to say about algebraic data types + later, but this quick introduction will help us to understand + lists, which we're about to encounter again. + + + + Lists + + We've already seen the list type mentioned in , where we found that Haskell + represents a text string as a list of Char + values, and that the type list of + Char is written + [Char]. + + More generally, we can write the type list of + a for any type + a by enclosing it in square + brackets, [a]. + + Like the Bool type, a list is an algebraic + data type. There are only two ways to construct a list. One + constructor is the empty list, written []. + + &list.ghci:empty; + + The other is the : operator, often + pronounced cons (this is short for + construct, and borrowed from Lisp). The + : operator takes an element and a list, and + constructs a new list. + + &list.ghci:cons; + + + addfile ./examples/ch03/ch03.basics.ghci hunk ./examples/ch03/ch03.basics.ghci 1 +--# error + +'j' :: Int addfile ./examples/ch03/list.ghci hunk ./examples/ch03/list.ghci 1 +--# empty + +[] + +--# cons + +1 : [] }