Skip to content
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

Adds List concept #59

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions concepts/lists/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"authors": [
"rlmark"
],
"blurb": "Using the List collection type in Unison"
}
61 changes: 61 additions & 0 deletions concepts/lists/about.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Unison Lists

Lists are used in the Unison programming language to represent a finite, ordered collection of elements. They're written with comma-separated elements in square braces:

```
emptyList = []

listNats : [Nat]
listNats = [1,2,3,4]

listText : [Text]
listText = ["hello", "world"]
```

Unison implements lists as a finger tree, allowing for fast access of the first and last element. You can read more about the underlying implementation in the [standard library List documentation][list-docs]. Appending single elements to either side of the list can be done with the `+:` and `:+` operators:

```
myList = [1,2,3,4]

> 0 +: myList :+ 5
[0, 1, 2, 3, 4, 5]
```

Concatenating lists is supported with the `++` operator:

```
> [1,2] ++ [3,4,5]
[1, 2, 3, 4, 5]
```

The standard library, `base` contains a variety of functions available for `List` transformations. Check them out by using the `find.all` command in the UCM or by exploring the `List` namespace in [Unison share][list-docs].

## List pattern matching

It's common to pattern match on the head and tail elements of a list with the `+:` syntax:

```
match ["a", " b", "c"] with
head +: tail -> head
otherwise -> "otherwise"
```

But in Unison you can also pattern match on the last element of a list, just reverse the operator:

```
match ["a", " b", "c"] with
prefix :+ last -> last
otherwise -> "otherwise"
```

Multi list element matching is supported by surrounding the desired elements in square brackets, followed by the concatenation operator, `++`. This expression will match any list with a length of two or more elements:

```
match ["a", " b", "c"] with
[first, second] ++ remainder -> first
otherwise -> "otherwise"
```

[list-docs]: https://share.unison-lang.org/@unison/code/latest/namespaces/public/base/latest/;/types/data/List
61 changes: 61 additions & 0 deletions concepts/lists/introduction.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Unison Lists

Lists are used in the Unison programming language to represent a finite, ordered collection of elements. They're written with comma-separated elements in square braces:

```
emptyList = []

listNats : [Nat]
listNats = [1,2,3,4]

listText : [Text]
listText = ["hello", "world"]
```

Unison implements lists as a finger tree, allowing for fast access of the first and last element. You can read more about the underlying implementation in the [standard library List documentation][list-docs]. Appending single elements to either side of the list can be done with the `+:` and `:+` operators:

```
myList = [1,2,3,4]

> 0 +: myList :+ 5
[0, 1, 2, 3, 4, 5]
```

Concatenating lists is supported with the `++` operator:

```
> [1,2] ++ [3,4,5]
[1, 2, 3, 4, 5]
```

The standard library, `base` contains a variety of functions available for `List` transformations. Check them out by using the `find.all` command in the UCM or by exploring the `List` namespace in [Unison share][list-docs].

## List pattern matching

It's common to pattern match on the head and tail elements of a list with the `+:` syntax:

```
match ["a", " b", "c"] with
head +: tail -> head
otherwise -> "otherwise"
```

But in Unison you can also pattern match on the last element of a list, just reverse the operator:

```
match ["a", " b", "c"] with
prefix :+ last -> last
otherwise -> "otherwise"
```

Multi list element matching is supported by surrounding the desired elements in square brackets, followed by the concatenation operator, `++`. This expression will match any list with a length of two or more elements:

```
match ["a", " b", "c"] with
[first, second] ++ remainder -> first
otherwise -> "otherwise"
```

[list-docs]: https://share.unison-lang.org/@unison/code/latest/namespaces/public/base/latest/;/types/data/List
18 changes: 18 additions & 0 deletions concepts/lists/links.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[
{
"url": "https://www.unison-lang.org/learn/fundamentals/values-and-functions/common-collection-types/#lists",
"description": "Lists and other common collection types in Unison"
},
{
"url": "https://www.unison-lang.org/learn/fundamentals/control-flow/pattern-matching2/#pattern-matching-on",
"description": "List pattern matching"
},
{
"url": "https://share.unison-lang.org/@unison/code/latest/namespaces/public/base/latest/;/types/data/List",
"description": "List documentation from the standard library"
},
{
"url": "https://www.unison-lang.org/learn/fundamentals/control-flow/looping/",
"description": "Tips for using recursion using a List example"
}
]
15 changes: 15 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,16 @@
"concepts": ["basics"],
"difficulty": 1,
"status": "wip"
},
{
"slug": "language-list",
"name": "Language List",
"uuid": "5ebdb25b-39a0-4cd8-9f73-04ec565ef15f",
"practices": [],
"prerequisites": [],
"concepts": ["lists"],
"difficulty": 2,
"status": "wip"
}
],
"practice": [
Expand Down Expand Up @@ -282,6 +292,11 @@
"uuid": "24332ec2-07b2-49e5-aa58-4829d31dc44a",
"slug": "basics",
"name": "Basics"
},
{
"uuid": "44f2d0c1-73db-487a-a2d2-aea4fa7be73f",
"slug": "lists",
"name": "Lists"
}
],
"key_features": [
Expand Down
41 changes: 41 additions & 0 deletions exercises/concept/language-list/.docs/hints.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Hints

## General

- Use the built-in [list type][list].
- In functional programming it's common to iterate through, inspect, or manipulate lists by [recursively pattern matching][functional-looping] on their elements until reaching the end of the list. In fact, many of the common functions defined for the list data type are based on these principles.

## 1. Define a function to return an empty language list

- You need to define a [Unison function function][named-function] with 0 arguments.

## 2. Define a function to add a language to the list

- You need to define a function with 2 arguments. The first argument is a [text literal value][string]. The second argument is a [list][list] of language [text literals][string].
- The list data type has a number of operators for manipulating lists, the "cons" (aka prepend) operator looks like `+:`.

## 3. Define a function to remove the left-most language from the list

- You need to define a function with 1 argument. The first argument is a [list][list] of language [text literals][string].
- Check out Unison's syntax for [pattern matching on list elements][list-patterns]. Pattern matching allows you to decompose the list into its constituent parts.

## 4. Define a function to return how many elements are in the list

- You need to define a function which takes in a [list][list] of language [text literals][string] and returns the size as a `Nat`.
- It's common to keep a running count of the number of elements seen using [recursion][functional-looping].

## 5. Define a function to determine if the list includes a given language

- You need to define a function with 2 arguments. The first is a [text][string] value and the second argument is a [list][list] of language [text literals][string].

## 6. Define a function to reverse a given list

- You need to define a function with 1 argument: the `List` of `Text` values.
- What happens if you call `List.foldLeft` on your list, passing in the `+:` operator as the first argument? What happens if you call `List.foldRight` with the `+:` argument?

[list]: https://share.unison-lang.org/@unison/code/latest/namespaces/public/base/latest/;/types/data/List
[string]: https://www.unison-lang.org/learn/language-reference/literals/
[list-patterns]: https://www.unison-lang.org/learn/fundamentals/control-flow/pattern-matching2/#pattern-matching-on
[size]: https://share.unison-lang.org/@unison/code/latest/namespaces/public/base/latest/;/terms/data/List/size
[optional]: https://share.unison-lang.org/@unison/code/latest/namespaces/public/base/latest/;/types/Optional
[functional-looping]: https://www.unison-lang.org/learn/fundamentals/control-flow/looping/#functional-looping
84 changes: 84 additions & 0 deletions exercises/concept/language-list/.docs/instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# Instructions

In this exercise you need to implement some functions to manipulate a list of programming languages. Some of the functions you'll be asked to define may exist for `List`, which is good to know for future reference, but for this exercise try not to use them!
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the bit of text starting with "Some of the functions", you could consider putting them in a special block: https://exercism.org/docs/building/markdown/markdown#h-special-blocks-sometimes-called-admonitions


## 1. Define a function to return an empty language list

Define the `new` function that takes no arguments and returns an empty list.

```
languageList.new : [Text]
languageList.new = todo "return empty list"
```

## 2. Define a function to add a language to the list

Define the `add` function that takes 2 arguments (a list of languages and a string literal of a language). It should return the resulting list with the new language added to the front of the given list.

```
> languageList.new
|> languageList.add "Clojure"
|> languageList.add "Unison"
["Unison", "Clojure"]
```

## 3. Define a function to remove the left-most language from the list

Define the `drop1` function that takes 1 argument (a list of languages). It should return the list without the first item. Calling `drop1` on an empty list should return an empty list.

```
> languageList.new
|> languageList.add "Clojure"
|> languageList.add "Unison"
|> languageList.drop1
["Clojure"]
```

## 4. Define a function to return how many elements are in the list

Define the `size` function that takes 1 argument (a list of languages). It should return the number of languages in the list.

```
> languageList.new
|> languageList.add "Elm"
|> languageList.add "Prolog"
|> languageList.size
2
```

## 5. Define a function to determine if the list includes a given language

Define the `contains` function which takes 1 argument (a list of languages). It should return a boolean value. It should return true if the desired language is one of the languages in the list.

```
> languageList.new
|> languageList.add "Unison"
|> languageList.add "Clojure"
|> languageList.contains "Unison"
true
```

## 6. Define a function to reverse a given list

Define the `reverse` which takes in a list and returns the list with the elements in reverse order.

```
list1 =
languageList.new
|> languageList.add "Clojure"
|> languageList.add "Scala"
|> languageList.add "Unison"
|> languageList.add "Elm"

> list1
["Elm", "Unison", "Scala", "Clojure"]

> languageList.reverse list1
["Clojure", "Scala", "Unison", "Elm"]
```
61 changes: 61 additions & 0 deletions exercises/concept/language-list/.docs/introduction.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Unison Lists

Lists are used in the Unison programming language to represent a finite, ordered collection of elements. They're written with comma-separated elements in square braces:

```
emptyList = []

listNats : [Nat]
listNats = [1,2,3,4]

listText : [Text]
listText = ["hello", "world"]
```

Unison implements lists as a finger tree, allowing for fast access of the first and last element. You can read more about the underlying implementation in the [standard library List documentation][list-docs]. Appending single elements to either side of the list can be done with the `+:` and `:+` operators:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do students need to know about the underlying implementation? I guess they don't, in which case it might be best to remove it here and just have it in the about.md document.


```
myList = [1,2,3,4]

> 0 +: myList :+ 5
[0, 1, 2, 3, 4, 5]
```

Concatenating lists is supported with the `++` operator:

```
> [1,2] ++ [3,4,5]
[1, 2, 3, 4, 5]
```

The standard library, `base` contains a variety of functions available for `List` transformations. Check them out by using the `find.all` command in the UCM or by exploring the `List` namespace in [Unison share][list-docs].

## List pattern matching

It's common to pattern match on the head and tail elements of a list with the `+:` syntax:

```
match ["a", " b", "c"] with
head +: tail -> head
otherwise -> "otherwise"
```

But in Unison you can also pattern match on the last element of a list, just reverse the operator:

```
match ["a", " b", "c"] with
prefix :+ last -> last
otherwise -> "otherwise"
```

Multi list element matching is supported by surrounding the desired elements in square brackets, followed by the concatenation operator, `++`. This expression will match any list with a length of two or more elements:

```
match ["a", " b", "c"] with
[first, second] ++ remainder -> first
otherwise -> "otherwise"
```

[list-docs]: https://share.unison-lang.org/@unison/code/latest/namespaces/public/base/latest/;/types/data/List
20 changes: 20 additions & 0 deletions exercises/concept/language-list/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"authors": [
"rlmark"
],
"files": {
"solution": [
"languageList.u"
],
"test": [
"languageList.test.u"
],
"exemplar": [
".meta/examples/languageList.example.u"
]
},
"forked_from": [
"elixir/language-list"
],
"blurb": "Learn about lists by keeping track of the programing languages you're currently learning on Exercism."
}
Loading