-
-
Notifications
You must be signed in to change notification settings - Fork 195
Add Lists concept #1134
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Add Lists concept #1134
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"authors": ["MatthijsBlom"], | ||
"contributors": [], | ||
"blurb": "Lists in Haskell are homogenous lazy linked lists. Depending on your needs, they can serve as data containers, generators, or streams. In this concept node you'll learn about list literal syntax, types of lists, and where to find documentation on functions that operate on lists." | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# About | ||
|
||
%{concept:lists} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,182 @@ | ||
# Introduction | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This introduction document is quite large. As per the docs, we want it to be as minimal as possible. |
||
|
||
The **list** might well be Haskell's most important data structure. | ||
|
||
|
||
## Syntax | ||
|
||
Here are some examples of lists. | ||
|
||
```haskell | ||
someIntegers = [3, -1, 4, 1, 5] -- a list of integers | ||
someDoubles = [9.2, 6.53, 5.89] -- a list of decimal numbers | ||
someBools = [True, False] -- a list of booleans | ||
someChars = ['H', 'i', '!'] -- a list of characters | ||
someFunctions = [isUpper, isSpace] -- a list of functions | ||
emptyList = [] -- an empty list | ||
``` | ||
~~~~exercism/advanced | ||
The above expressions are called **list literals**, because just like number literals (`9`, `1.6`) the syntax is special. | ||
Less syntactically special ways of building lists exist. | ||
We'll get to those when we learn about **algebraic data types** and **pattern matching**. | ||
~~~~ | ||
|
||
For some types of elements, a shorthand for ranges is available: | ||
|
||
```haskell | ||
someOddNumbers = [9, 11 .. 17] -- [9, 11, 13, 15, 17] | ||
firstHalfOfAlphabet = ['a' .. 'm'] -- "abcdefghijklm" | ||
everySecondLetter = ['b', 'd' .. 'z'] -- "bdfhjlnprtvxz" | ||
multiplesOf7 = [0, 7 ..] -- infinite list [0, 7, 14, 21, …] | ||
positiveIntegers = [1 ..] -- infinite list [1, 2, 3, …] | ||
``` | ||
|
||
~~~~exercism/caution | ||
Do not ask your computer to print an infinite list, or to otherwise process all its elements. | ||
Even though much faster than you, it'll never finish. | ||
|
||
Asking for a finite amount of work is fine though: | ||
|
||
```haskell | ||
ghci> take 5 [0, 3 ..] | ||
[0,3,6,9,12] | ||
``` | ||
~~~~ | ||
|
||
|
||
## List types | ||
|
||
In Haskell, lists are **homogenous**. | ||
This means that all elements of a list have the same type. | ||
When you try to put elements of different types into the same list, you will get a type error. | ||
|
||
```haskell | ||
heterogenousList = [True, 'X'] | ||
-- […]: error: | ||
-- • Couldn't match expected type ‘Bool’ with actual type ‘Char’ | ||
-- • In the expression: 'X' | ||
``` | ||
|
||
Because elements's types are always the same, it makes sense to speak of _lists of integers_, _lists of booleans_, _lists of functions_, etc. | ||
Indeed, all of these kinds of lists have their own types! | ||
|
||
```haskell | ||
ghci> :type someBools | ||
someBools :: [Bool] -- the type of lists of booleans | ||
ghci> :type someChars | ||
someChars :: [Char] -- the type of lists of characters | ||
ghci> :type someFunctions | ||
someFunctions :: [Char -> Bool] -- the type of lists of functions | ||
``` | ||
|
||
~~~~exercism/note | ||
As you can see, the `[…]` syntax is slightly overloaded: it can denote both values and types. | ||
It is however never truly ambiguous, because of strictly distinguished syntactical contexts: | ||
|
||
```haskell | ||
name :: {- only types here -} | ||
name = {- only values here -} | ||
``` | ||
|
||
To add to that, | ||
|
||
- `[a, b, c]` and `[]` are values | ||
- `[6]`, `[True]`, `[[]]` are values, because `6`, `True`, `[]` are all values | ||
- `[Bool]` is a type, because `Bool` is a type | ||
- `[a]` is a type when `a` is a type variable, and a value otherwise. | ||
~~~~ | ||
|
||
~~~~exercism/advanced | ||
The family of types of lists has a name: `[]`. | ||
It is, strictly speaking, not a type itself. | ||
Instead, it is a _type constructor_, or _parametric type_. | ||
We'll get to what this means exactly in subsequent concept nodes. | ||
|
||
When you hear people talk about «the `[]` type», most likely they mean this family of types rather than any specific type. | ||
~~~~ | ||
|
||
|
||
## Lists representing text: `String` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would probably extract this to a separate concept. |
||
|
||
Haskell does not have a built-in data type for representing text. | ||
Instead, by default it represents text as lists of characters. | ||
|
||
```haskell | ||
['H', 'i', '!'] -- a greeting: a list of characters | ||
``` | ||
|
||
Lists of characters are syntactically unwieldy, so Haskell features some handy syntactic sugar: | ||
|
||
```haskell | ||
ghci> ['H', 'i', '!'] == "Hi!" | ||
True | ||
ghci> "" == [] | ||
True | ||
``` | ||
|
||
~~~~exercism/note | ||
In contrast to in some other languages, in Haskell single quotes (`'`) and double quotes (`"`) are not interchangeable. | ||
Single quotes denote `Char`acters, whereas double quotes denote `String`s (i.e. lists of characters). | ||
|
||
```haskell | ||
ghci> :type 'a' | ||
'a' :: Char | ||
ghci> :type "a" | ||
"a" :: String | ||
``` | ||
~~~~ | ||
|
||
Also for convenience, Haskell provides the name `String`, which is a _type synonym_ of `[Char]`. | ||
Two names for exactly the same type, they are entirely interchangeable: | ||
|
||
```haskell | ||
ghci> (['H', 'i', '!'] :: String) == ("Hi!" :: [Char]) | ||
True | ||
``` | ||
|
||
|
||
## Working with lists | ||
|
||
Owing to lists' ubiquitousness, lots of utilities for working with them are present in the standard library. | ||
|
||
The very most important functions you'll find in [the `Prelude`][prelude]. | ||
Other much-used functions live in [the `Data.List` module][data.list]. | ||
Be sure to have a good look-around! | ||
|
||
Functions that are provided by the `Prelude` you do not need to import, as the `Prelude` itself is implicitly imported by default. | ||
Functions from `Data.List` however you do need to explicitly import. | ||
|
||
~~~~exercism/advanced | ||
Haskell's lists are singly-linked lists. | ||
This has consequences in performance characteristics of list operations. | ||
For example, `length` takes time proportional to list length, `!!` (index) takes time linear in the index, and `++` (append) takes time proportional to (only!) the length of the left operand. | ||
~~~~ | ||
|
||
|
||
### How to interpret `Foldable` constraints | ||
|
||
In many places in the documentation you'll find functions with signatures mentioning `Foldable`, e.g. | ||
|
||
```haskell | ||
length :: Foldable t => t a -> Int | ||
``` | ||
|
||
We'll get to what this means exactly later. | ||
For now, you can read all such signatures as if they are about lists: | ||
|
||
```haskell | ||
-- 1. remember this name | ||
-- 👇 | ||
length :: Foldable t => t a -> Int | ||
-- 👆 | ||
-- 2. replace all occurrences with […] | ||
-- 👆 | ||
-- 3. remove constraint | ||
|
||
-- Result: | ||
length :: [a] -> Int | ||
``` | ||
|
||
|
||
[data.list]: https://hackage.haskell.org/package/base/docs/Data-List.html "Data.List documentation" | ||
[prelude]: https://hackage.haskell.org/package/base/docs/Prelude.html "Prelude documentation" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
[ | ||
{ | ||
"url": "https://learnyouahaskell.github.io/starting-out.html#an-intro-to-lists", | ||
"description": "Learn You A Haskell's introduction to lists" | ||
}, | ||
{ | ||
"url": "https://learnyouahaskell.github.io/modules.html#data-list", | ||
"description": "Learn You A Haskell's tour of `Data.List`" | ||
}, | ||
{ | ||
"url": "https://en.wikibooks.org/wiki/Haskell/Lists_and_tuples", | ||
"description": "Haskell Wikibook's introduction to lists" | ||
}, | ||
{ | ||
"url": "https://hackage.haskell.org/package/base/docs/Prelude.html", | ||
"description": "Prelude documentation" | ||
}, | ||
{ | ||
"url": "https://hackage.haskell.org/package/base/docs/Data-List.html", | ||
"description": "Data.List documentation" | ||
}, | ||
{ | ||
"url": "https://hoogle.haskell.org/", | ||
"description": "Hoogle" | ||
} | ||
] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is no such thing as an
about.md.tpl
file.The reason for that is that the about.md file should have different, more extensive contents than the introduction.
See https://exercism.org/docs/building/tracks/concepts