Notes (HPFP 03/31): Strings

3 Strings

string: a sequence of characters, usually representing text. The words you are reading now are strings.

Haskell’s String type: A particular way of representing strings as lists of Char types. It is very important to notice that even though the name of this type is String, it is not the only, or even the best way to represent sequences of characters and text. (see Data.Text and Data.ByteString

The main advantage of String is that it is conceptually very simple: a String is a List of Char (in the abstract, that is. The acutual implementation of String is a linked list of Char, which is sometimes not that simple from a performance perspective.)

Lists

A list (with a lowercase l) is some ordered collection of information. The order may not be important, but if there is no order, it’s not a list, it’s a set (“unordered list” is a bit of a misnomer).

Suppose you buy groceries for your family every week. You want to know what everyone else wants from the store without having to talk to them each individually, so you put a piece of paper on the fridge and tell everyone to write down what they want you to get. This is an everyday example of a list: A grocery list.

A grocery list is an everyday example of a list. The order of your grocery list probably isn’t important but there definitely is an order: The groceries aren’t written randomly all over the page, but in parallel lines starting from the top of the page downward.

The order of the list could indicate the chronological order in which people added their requests. That’s probably not important information most of the time, but occasionally it might be.

In the above example, notice that the first item on the list is Milk. If the list is chronological, it means that Milk was the first thing added since you went to the store last week. If you know you bought a half-gallon of Milk last week, that probably means your family drank all the Milk right after you bought it. And that might make you decide to buy a whole gallon this time.

Another interesting thing you can see in the ordering of a grocery list is that items that are next to each other are likely to be connected to each other conceptually. The last three items: mushrooms, Beef tenderloin, Puff pastry are all ingredients for a Beef Wellington recipe. If the store happens to be all out of puff pastry, it might make sense to skip the mushrooms and the beef, since you can’t make the recipe.

Okay, so a grocery list has an ordering that’s sometimes relevant.

Here’s a slightly philosophical question: Was the grocery list a list before someone added the first item (Milk) to it?

In common language, we probably wouldn’t call a blank piece of paper a list. But we could perhaps call a piece of paper with the title Grocery List at the top a “blank grocery list”, or an “empty grocery list”, although that might sound strange.

In Haskell-land (and CS-country in general), an empty list is definitely a list. List in Haskell is defined as follows:

Nil is the empty list. We build lists by connecting the items in the list to each other and ultimately to the empty list. So the above definition says roughly: “A list of a is either an empty list, or is the connection of an a to a List of a.

Since a is just a stand-in for some type of thing, a list of groceries in Haskell would be:

Most of the first 32 are control characters intended for use by teletype machines and magnetic tape readers, so you don’t have to worry about them. A few are still used though, \n in Haskell means newline and is the same as ASCII 10 \LF.

3.4 Top-level versus local definitions

Exercises: Scope

y is in scope for z

h is not in scope for g

pi is in scope, since it’s in Prelude, but d is not in scope for the definition of r. d is an argument in area but r can’t see into area’s definition.

This fixes what was wrong in the previous question. The where clause means that r can access area’s arguments. However, r is now locally defined to area, so another top level function wouldn’t be able to see it.