Skip to content

Commit

Permalink
Decrease all header levels by one
Browse files Browse the repository at this point in the history
  • Loading branch information
MatthijsBlom committed Feb 6, 2024
1 parent 000e69d commit a434b8a
Show file tree
Hide file tree
Showing 16 changed files with 53 additions and 85 deletions.
16 changes: 7 additions & 9 deletions exercises/practice/bob/.approaches/introduction.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
# Introduction

This problem requires checking against a series of conditions, each associated with a desired output.
This suggests using guards.


## General guidance
# General guidance

### Beware partial functions
## Beware partial functions

This problem might tempt you into reaching for `last`.
However, you should know that it is dangerous:
Expand All @@ -25,7 +23,7 @@ For this reason, strive to avoid partial functions.
It is almost always fairly easy to do so.


### Avoid duplicating code
## Avoid duplicating code

At multiple points in your solution you'll need to know whether the query is a question, or yelled.
Do not copy–paste the code for determining this.
Expand All @@ -34,7 +32,7 @@ Instead, give meaningful names to these computations and then use these names to
Likewise, if you strip the query, do so only once.


### `where` clauses are your friend!
## `where` clauses are your friend!

Giving meaningful names to subexpressions can do wonders for code readability.
`where` clauses allow you to list local definitions at the end of the declaration.
Expand All @@ -48,7 +46,7 @@ More on `where` elsewhere:
- Haskell Wiki: [Let vs. Where][haskellwiki-let-vs-where]


### When possible, consider turning functions into constants
## When possible, consider turning functions into constants

Many beginning Haskellers write code like

Expand Down Expand Up @@ -104,7 +102,7 @@ responseFor query
```


## Approach: using `String`
# Approach: using `String`

```haskell
responseFor :: String -> String
Expand All @@ -126,7 +124,7 @@ It also eschews `last`, which is [partial][wiki-partial-functions], in favor of
[Read more about this approach][string].


## Approach: using `Text`
# Approach: using `Text`

```haskell
responseFor :: Text -> Text
Expand Down
8 changes: 3 additions & 5 deletions exercises/practice/bob/.approaches/string/content.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
# Using `String`

```haskell
responseFor :: String -> String
responseFor query
Expand All @@ -18,7 +16,7 @@ This solution uses `any` and `all` to determine whether the query consists entir
It also eschews `last`, which is [partial][wiki-partial-functions], in favor of the safe alternative `lastMay`.


## Using dependencies
# Using dependencies

The function `lastMay` lives in the `Safe` module of the external `safe` package.
To be able to use it, you need to add this package to the list of dependencies in `package.yaml`:
Expand All @@ -36,7 +34,7 @@ import Safe (lastMay)
```


## `any` & `all`
# `any` & `all`

`any` and `all` are **higher-order functions** that take a predicate (a function that produces a `Boolean`) and a list as arguments.
Both check whether elements of the list satisfy the predicate.
Expand Down Expand Up @@ -113,7 +111,7 @@ And thanks to laziness, `any` and `all` even work on infinite lists!
Provided the answer can be determined after looking at finitely many elements, that is.


## In this approach
# In this approach

A query is considered silent when it consists entirely of whitespace characters.
Which is to say: it is silent when _all_ of its characters are whitespace.
Expand Down
10 changes: 4 additions & 6 deletions exercises/practice/bob/.approaches/text/content.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
# Using `Text`

```haskell
responseFor :: Text -> Text
responseFor (strip -> query)
Expand All @@ -19,7 +17,7 @@ This solution works with `Text` instead, which is a data type designed specifica
It also employs a _view pattern_.


## Using dependencies
# Using dependencies

The `Text` type and associated functions live in the `Data.Text` module of the external `text` package.
To be able to use it, you need to add this package to the list of dependencies in `package.yaml`:
Expand All @@ -41,7 +39,7 @@ import qualified Data.Text as Text
```


## Language extensions
# Language extensions

For various reasons, some of GHC's features are locked behind switches known as _language extensions_.
You can enable these by putting so-called _language pragmas_ at the top of your file:
Expand All @@ -59,7 +57,7 @@ module Bob (responseFor) where
```


### `OverloadedStrings`
## `OverloadedStrings`

By default, `"abc"` is interpreted by the compiler as denoting a `String`.
To get a `Text` value instead, you need to explicitly convert using `Text.pack`:
Expand All @@ -82,7 +80,7 @@ someText = "abc"
```


### `ViewPatterns`
## `ViewPatterns`

Recall, patterns occur in the following positions:

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
# Introduction

This problem requires iteratively computing the next number in a sequence, until `1` is reached.


## Approach: generate a list of steps
# Approach: generate a list of steps

```haskell
-- Using `iterate`
Expand Down Expand Up @@ -39,7 +37,7 @@ using only functions from the standard library for all of these except one.
[Read more about this approach][list-of-steps].


## Approach: recursion
# Approach: recursion

```haskell
collatz :: Integer -> Maybe Integer
Expand All @@ -54,7 +52,7 @@ While arguably elegant, this approach suffers space usage linear in the number o
[Read more about this approach][recursion].


## Approach: a worker–wrapper construct
# Approach: a worker–wrapper construct

```haskell
collatz :: Integer -> Maybe Integer
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
# Generate a list of steps

```haskell
-- Using `iterate`
collatz :: Integer -> Maybe Integer
Expand Down Expand Up @@ -32,7 +30,7 @@ This approach neatly disentangles all four concerns of
using only functions from the standard library for all of these except one.


## `iterate` and `unfoldr`
# `iterate` and `unfoldr`

When you have a 'seed' element and a way of computing every next element from it, you can use `iterate` or `unfoldr` to produce the entire sequence.

Expand Down Expand Up @@ -79,7 +77,7 @@ iterate :: (a -> a) -> a -> [a]
iterate f = unfoldr (\x -> Just (x, f x))
```

## In this approach
# In this approach

Given any number, `nextStep` will compute the next Collatz number.
This is the only logic that is provided by us instead of by the standard library.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
# Recursion

```haskell
collatz :: Integer -> Maybe Integer
collatz n = case compare n 1 of
Expand All @@ -12,7 +10,7 @@ The number of steps it takes to get to `1` is one plus however many more steps i
This suggest a recursive solution.


## Recursion
# Recursion

[Recursion][wikipedia-recursion] in Haskell is the phenomenon of functions or values being defined in terms of themselves.
For example, here is a recursive definition of an (infinite) list:
Expand Down Expand Up @@ -71,7 +69,7 @@ Haskell does not provide any dedicated loop devices such as many other languages
Instead, all 'loopiness' in Haskell is produced through recursion – if not by you then under the hood of some of the functions you use.


## In this approach
# In this approach

First, we compare the input with `1`.
If it is less than `1` then the input is invalid and we return `Nothing`.
Expand Down Expand Up @@ -126,7 +124,7 @@ theAnswer =
(1 +) <$> collatz (if even n then n `div` 2 else 3 * n + 1)
```

## Considerations on this approach
# Considerations on this approach

In a way, this solution is elegant.
However, it suffers an inefficiency.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
# Worker&ndash;wrapper

```haskell
collatz :: Integer -> Maybe Integer
collatz n
Expand All @@ -14,7 +12,7 @@ This approach uses an inner _worker_ function to simultaneously calculate succes
It also uses a _bang pattern_ to force intermediate evaluation, to guarantee decent space efficiency.


## The worker&ndash;wrapper construct
# The worker&ndash;wrapper construct

Sometimes, when solving a problem, it is more convenient or efficient to keep track of some kind of _state_.
Many other languages use local variables for this.
Expand Down Expand Up @@ -95,7 +93,7 @@ The worker&ndash;wrapper pattern is more general than demonstrated here.
For a few more more examples, see the [relevant wiki article][wiki-worker-wrapper], and for yet more examples and an explanation of the general pattern see the paper «[The worker/wrapper transformation][paper-worker-wrapper]» (pdf).


## Bang patterns
# Bang patterns

The above implementation of `length'` _might_ evaluate as efficiently as illustrated.
However, depending on which optimization opportunities are spotted by the compiler, it also might not!
Expand Down
8 changes: 3 additions & 5 deletions exercises/practice/hamming/.approaches/introduction.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
# Introduction

To solve this problem, you need to

- check that the two inputs have the same length, and
Expand All @@ -8,7 +6,7 @@ To solve this problem, you need to
The desired output is `Nothing` if the inputs are not equally long, and `Just numberOfDifferences` otherwise.


## Approach: `zipWith`
# Approach: `zipWith`

```haskell
distance :: String -> String -> Maybe Int
Expand All @@ -30,7 +28,7 @@ While this style of solution might suffer some inefficiency, it should not be di
[Read more about this approach][zipwith]


## Approach: hand-written recursion
# Approach: hand-written recursion

```haskell
distance :: String -> String -> Maybe Int
Expand All @@ -50,7 +48,7 @@ You can use `fmap`/`<$>` for this.
[Read more about this approach][recursion]


## Approach: a worker&ndash;wrapper construct
# Approach: a worker&ndash;wrapper construct

```haskell
distance :: String -> String -> Maybe Int
Expand Down
8 changes: 3 additions & 5 deletions exercises/practice/hamming/.approaches/recursion/content.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
# Recursion

```haskell
distance :: String -> String -> Maybe Int
distance [] [] = Just 0
Expand All @@ -8,7 +6,7 @@ distance (x : xs) (y : ys) =
distance _ _ = Nothing
```

## Recursion
# Recursion

[Recursion][wikipedia-recursion] in Haskell is the phenomenon of functions or values being defined in terms of themselves.
For example, here is a recursive definition of an (infinite) list:
Expand Down Expand Up @@ -67,7 +65,7 @@ Haskell does not provide any dedicated loop devices such as many other languages
Instead, all 'loopiness' in Haskell is produced through recursion &ndash; if not by you then under the hood of some of the functions you use.


## In this approach
# In this approach

If both inputs are empty, then they are of equal length and they do not have any differing elements, so `Just 0` should be returned.

Expand Down Expand Up @@ -143,7 +141,7 @@ distance _ _ = Nothing
```


## Considerations on this approach
# Considerations on this approach

In a way, this solution is elegant.
However, it suffers an inefficiency.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
# Worker&ndash;wrapper

```haskell
distance :: String -> String -> Maybe Int
distance = go 0
Expand All @@ -13,7 +11,7 @@ This approach uses an inner _worker_ function to simultaneously walk both lists
It also uses a _bang pattern_ to force intermediate evaluation, to guarantee decent space efficiency.


## The worker&ndash;wrapper construct
# The worker&ndash;wrapper construct

Sometimes, when solving a problem, it is more convenient or efficient to keep track of some kind of _state_.
Many other languages use local variables for this.
Expand Down Expand Up @@ -94,7 +92,7 @@ The worker&ndash;wrapper pattern is more general than demonstrated here.
For a few more more examples, see the [relevant wiki article][wiki-worker-wrapper], and for yet more examples and an explanation of the general pattern see the paper «[The worker/wrapper transformation][paper-worker-wrapper]» (pdf).


## Bang patterns
# Bang patterns

The above implementation of `length'` _might_ evaluate as efficiently as illustrated.
However, depending on which optimization opportunities are spotted by the compiler, it also might not!
Expand Down
8 changes: 3 additions & 5 deletions exercises/practice/hamming/.approaches/zipwith/content.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
# `zipWith`

```haskell
distance :: String -> String -> Maybe Int
distance xs ys
Expand All @@ -13,7 +11,7 @@ The most straightforward way of solving this problem is to
- iterate over both inputs together to count their differences.


## Higher-order functions
# Higher-order functions

Higher-order functions are functions that take functions as arguments.
Examples well-known even outside of Haskell are `map` and `filter`.
Expand Down Expand Up @@ -65,7 +63,7 @@ Still other examples include
```


## In this approach
# In this approach

After making sure that the lengths are equal, we count the number of places in which the inputs differ.

Expand Down Expand Up @@ -125,7 +123,7 @@ distance xs ys
```


## Considerations on this approach
# Considerations on this approach

This style of solution is very easy to understand.
This is a very important quality for code to have!
Expand Down
Loading

0 comments on commit a434b8a

Please sign in to comment.