Values, types and the first program
What runs when you press Run, how a value becomes text with show, and the small set of types every line in this course is built from.
A program is a value you run
A Haskell file is a set of definitions. Nothing happens until the page asks for a value to carry out, and the value it asks for is always named main. Every example in this course gives main the type IO (), which means: an action that prints something.
Inside main, the word do lines up several actions and runs them in order, top to bottom. A file without main is perfectly legal and prints nothing at all, because there is nothing to run. The file is compiled as a whole before any of it runs, so a definition with a mistake is reported even when main never calls it.
Reading a signature
A signature is written name, two colons, then the type. main :: IO () says that main is an action, and the empty brackets are the unit type: the action produces nothing worth keeping, only the effect of printing. putStrLn :: String -> IO () says the function takes text and answers an action.
The arrow is the important part. Int -> Int is a function, not a pair of types, and Int -> String -> Bool is a function that takes a number and answers a function that takes text and answers a Bool. That is why an argument can be supplied one at a time. Reading a signature aloud, with the word then at every arrow, is the fastest way to understand a function you did not write.
Every value has a type
Types are written down, not discovered at run time. A whole number is an Int, a decimal number is a Double, text is a String, a yes or no value is a Bool, and a single letter is a Char in single quotes while a String wears double quotes.
show turns a value into the text that represents it, so you can join it to a sentence with ++. Without show, a number is not text and the two cannot be joined: the compiler says so instead of quietly mixing them.
Printing a value, printing text
main :: IO ()
main = do
putStrLn "a line of text"
putStrLn ("a number: " ++ show 42)
print 42
print "text"Five lines, five kinds of value
Run it and read the five lines. Then change the arithmetic to something else and add a line of your own that prints a Double and a Bool.
putStrLn writes a line and moves to the next one, while putStr leaves the cursor where it is. print writes any value with show, so printing text puts the quotes back on: that is the difference you can see between the last two lines of the snippet.
Two kinds of quote
A Char is one character in single quotes, and a String is a list of those characters in double quotes. 'h' and "h" look nearly the same on the page and are different types: one is a letter, the other is a list holding that letter.
putStrLn wants a String, so putStrLn 'h' is refused while putStrLn "h" prints. When you have a Char and need text, put it in a list: ['h'] is the same value as "h", which is why putStrLn [initial] works in the example below.
show is not the same as those quote marks. It is a function that every printable type has, and it writes the value the way you would type it back in: show 'h' keeps the single quotes around the letter, while show "h" keeps the double quotes around the text.
A do block is a sequence of actions
The lines inside do are actions, not values. putStrLn "hi" has the type IO (): an action that prints when it is run. Text on a line of its own is a value, and the block is waiting for something to carry out, so the compiler refuses it.
let is how a value joins the block. let n = 6 * 7 names a value for the lines below and runs nothing at all. There is no in after it inside do, because the rest of the block is the in.
Order matters here in a way it does not elsewhere in the language. The actions run from the top down, so a putStrLn that uses n has to come after the let that names it.
putStrLn 42 is refused, because the function wants text and a number is not text: use print 42, or putStrLn (show 42) when the number is part of a longer sentence. "x" ++ 42 is refused for the same reason, since ++ joins two lists. And a name cannot begin with a capital letter — Answer = 42 is read as a constructor, and the compiler rejects it.
Try these next
- Print a
Charon its own withputStrLn [c], then withshow c, and compare the two lines. - Name a
Booland aDoublewith type lines of their own, and print both inside one sentence. - Use
divandmodto print how many weeks and days 100 days makes.
A badge with six kinds of value
Run it and read the seven lines. Then add a `Char` for a middle initial and print it without its quote marks.
Check what you learned
One question at a time. A wrong answer explains itself — take another go.
Part 1 of 5
What does the page run when you press Run?
