Skip to content

Commit

Permalink
Convert backtick (`) admonition fences to tildes (~). (#1197)
Browse files Browse the repository at this point in the history
  • Loading branch information
ErikSchierboom authored Oct 6, 2023
1 parent bfe1031 commit e651c2d
Show file tree
Hide file tree
Showing 18 changed files with 74 additions and 74 deletions.
4 changes: 2 additions & 2 deletions concepts/tuples/about.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@ match person with
| name3, length3 -> printf "%s: %d" name3 length3
```

```exercism/note
~~~~exercism/note
Technically, you can access a tuples value using its `.Item1`, `.Item2`, ... properties, but this is discouraged and results in a compiler warning.
```
~~~~

## Key points about tuples

Expand Down
8 changes: 4 additions & 4 deletions exercises/practice/bob/.approaches/active-patterns/content.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ We can check for an empty string via the built-in [`String.IsNullOrWhiteSpace()`
if System.String.IsNullOrWhiteSpace(phrase) then Some () else None
```

````exercism/note
~~~~exercism/note
We opted for using `System.String`, but another option would be to open the `System` namespace and then we could omit the `System.` prefix for the `String.IsNullOrWhiteSpace` call:
```fsharp
Expand All @@ -77,7 +77,7 @@ let isEmpty = String.IsNullOrWhiteSpace(phrase)
```
If you were to use multiple types from the `System` namespace, we'd recommend using the above approach where the namespace is explicitly opened.
````
~~~~

Now that we can determine whether a phrase is empty, we can use this pattern in the `response` function:

Expand Down Expand Up @@ -179,10 +179,10 @@ match phrase with
| _ -> "Whatever."
```

```exercism/note
~~~~exercism/note
A downside of vertical alignment is that changes to the code require more work, as you'll need to ensure everything is still aligned.
For this particular case, it isn't really an issue, as the spec is fixed and the code is thus unlikely to change.
```
~~~~

### Final code

Expand Down
8 changes: 4 additions & 4 deletions exercises/practice/bob/.approaches/if/content.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ To check this, we can use the built-in [`String.IsNullOrWhiteSpace()`][string.is
let isEmpty = System.String.IsNullOrWhiteSpace(phrase)
```

````exercism/note
~~~~exercism/note
We opted for using `System.String`, but another option would be to open the `System` namespace and then we could omit the `System.` prefix for the `String.IsNullOrWhiteSpace` call:
```fsharp
Expand All @@ -42,7 +42,7 @@ let isEmpty = String.IsNullOrWhiteSpace(phrase)
```
If you were to use multiple types from the `System` namespace, we'd recommend using the above approach where the namespace is explicitly opened.
````
~~~~

Now that we can determine whether a phrase is empty, we can return the proper response using an [`if` expression][if-expressions]:

Expand Down Expand Up @@ -158,9 +158,9 @@ let response (phrase: string): string =
else "Whatever."
```

```exercism/note
~~~~exercism/note
We've defined the `isEmpty`, `isYell` and `isQuestion` bindings within the `response` function, as they're only used within that function.
```
~~~~

[if-expressions]: https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/conditional-expressions-if-then-else
[string.isnullorwhitespace]: https://learn.microsoft.com/en-us/dotnet/api/system.string.isnullorwhitespace
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ The `doSteps` function takes the number (basically, where we're at in the collat
let rec doSteps (current: int) (numberOfSteps: int)
```

```exercism/note
~~~~exercism/note
To allow a function to recursively call itself, the `rec` modified must be added.
In other words: by default, functions cannot call themselves.
```
~~~~

With the `doSteps` function,

Expand Down Expand Up @@ -80,12 +80,12 @@ doSteps number 0

And with that, we have a working, tail recursive implementation that correctly calculates the number of steps in a number's collatz sequence.

```exercism/note
~~~~exercism/note
Tail recursion prevents stack overflows when a recursive function is called many times.
While the exercise does not have large test cases that would cause a stack overflow, it is good practice to always use using tail recursion when implementing a recursive functions.
If you'd like to read more about tail recursion, [this MSDN article](https://blogs.msdn.microsoft.com/fsharpteam/2011/07/08/tail-calls-in-f/) goes into more detail.
Another good resource on tail recursion is [this blog post](http://blog.ploeh.dk/2015/12/22/tail-recurse/).
```
~~~~

## Pattern matching

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,10 @@ let rec private collatzSequence (current: int): int seq =

This function takes the current number as its sole parameter and is marked with `rec` to allow it to call itself.

```exercism/note
~~~~exercism/note
To allow a function to recursively call itself, the `rec` modified must be added.
In other words: by default, functions cannot call themselves.
```
~~~~

The body of the function has code wrapped in `seq {}`, which indicates to the compiler that we're generate a sequence.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ The first step is to calculate the distance from the center of the board, which
Math.Sqrt(x * x + y * y)
```

```exercism/note
~~~~exercism/note
We open the `System` namespace to allows us to use `Math.Sqrt` instead of `System.Math.Sqrt`.
```
~~~~

Before we'll look at the score calculation, let's re-iterate the games rules:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@ if strand1.Length <> strand2.Length
then None
```

```exercism/note
~~~~exercism/note
Note that we're using `string` class' `Length` property, not a function like `Seq.length`.
Even though F# is a functional-first language, you'll use types (like the `string` class) defined in the .NET framework, which is an object-oriented framework.
Inevitably, you'll thus use objects that have methods and properties defined on them.
Don't worry about using methods and objects though, F# is a multi-paradigm language and embraces the interaction with object-oriented code (like the `string` class).
```
~~~~

## Happy path

Expand Down
8 changes: 4 additions & 4 deletions exercises/practice/hamming/.approaches/recursion/content.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ This function takes the remaining letters for both strands as a `char list`, whi
Besides these two lists, we'll also take an _accumulator_ parameter: `distance`, of type `int`.
This parameter represents the current distance and is updated between the recursive function calls until we're done processing, at which point it will represent the total distance.

```exercism/note
~~~~exercism/note
To allow a function to recursively call itself, the `rec` modified must be added.
In other words: by default, functions cannot call themselves.
```
~~~~

Within this function, we pattern match on both letter lists at the same time, using:

Expand Down Expand Up @@ -78,11 +78,11 @@ doDistance (Seq.toList strand1) (Seq.toList strand2) 0

And with that, we have a working, tail recursive implementation!

```exercism/note
~~~~exercism/note
Tail call recursion prevents stack overflows when a recursive function is called many times.
While the exercise does not have large test cases that would cause a stack overflow, it is good practice to always use using tail recursion when implementing a recursive functions.
If you'd like to read more about tail recursion, [this MSDN article](https://blogs.msdn.microsoft.com/fsharpteam/2011/07/08/tail-calls-in-f/) goes into more detail.
Another good resource on tail recursion is [this blog post](http://blog.ploeh.dk/2015/12/22/tail-recurse/).
```
~~~~

[seq.tolist]: https://fsharp.github.io/fsharp-core-docs/reference/fsharp-collections-seqmodule.html#toList
4 changes: 2 additions & 2 deletions exercises/practice/hamming/.approaches/zip/content.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@ if strand1.Length <> strand2.Length then
None
```

```exercism/note
~~~~exercism/note
Note that we're using `string` class' `Length` property, not a function like `Seq.length`.
Even though F# is a functional-first language, you'll use types (like the `string` class) defined in the .NET framework, which is an object-oriented framework.
Inevitably, you'll thus use objects that have methods and properties defined on them.
Don't worry about using methods and objects though, F# is a multi-paradigm language and embraces the interaction with object-oriented code (like the `string` class).
```
~~~~

## Happy path

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ let rec doProteins (rna: string) (proteins: string list): string list
We'll define this function inside the `proteins` function (also known as a _nested_ function), but it could just as well have been defined outside the `proteins` function.
That said, its implementation _is_ merely a helper to the `proteins` function and is thus tied to that function, so to have it be close to where it is called often makes sense (it signals to the reader that the function should only be used _within_ its parent function).

```exercism/note
~~~~exercism/note
To allow a function to recursively call itself, the `rec` modified must be added.
In other words: by default, functions cannot call themselves.
```
~~~~

### Translating

Expand Down Expand Up @@ -78,11 +78,11 @@ There is one additional case we need to process, and that is when there are no c
| "" -> List.rev proteins
```

```exercism/note
~~~~exercism/note
We need to use [`List.rev`](https://fsharp.github.io/fsharp-core-docs/reference/fsharp-collections-listmodule.html#rev) to reverse the proteins, as translated proteins are added at the head of the list (in the front).
Prepending an element to a list is _much_ faster than appending an element.
In fact, it is so much faster that the penalty of having to reverse the list ends up being well worth it.
```
~~~~

### Unknown input

Expand Down Expand Up @@ -128,10 +128,10 @@ match rna[0..2] with
| _ -> failwith "Unknown coding"
```

```exercism/note
~~~~exercism/note
A downside of vertical alignment is that changes to the code require more work, as you'll need to ensure everything is still aligned.
For this particular case, it isn't really an issue, as the codons are fixed and the code is thus unlikely to change.
```
~~~~

## Putting it all together

Expand All @@ -143,9 +143,9 @@ doProteins rna []

And with that, we have a working, tail recursive implementation that translates the RNA to proteins.

```exercism/note
~~~~exercism/note
Tail recursion prevents stack overflows when a recursive function is called many times.
While the exercise does not have large test cases that would cause a stack overflow, it is good practice to always use using tail recursion when implementing a recursive functions.
If you'd like to read more about tail recursion, [this MSDN article](https://blogs.msdn.microsoft.com/fsharpteam/2011/07/08/tail-calls-in-f/) goes into more detail.
Another good resource on tail recursion is [this blog post](http://blog.ploeh.dk/2015/12/22/tail-recurse/).
```
~~~~
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ Let's define a `codonToProtein` function that takes a `string` parameter represe
let private codonToProtein (codon: string): string
```

```exercism/note
~~~~exercism/note
We could have defined this function as a nested function within the `proteins` function, but as it could reasonably be used _outside_ the `proteins` function, we chose not to.
```
~~~~

Within the function, we simply pattern match on the codon to translate it to its corresponding protein:

Expand Down Expand Up @@ -170,15 +170,15 @@ It is isn't the element is preserved, and the next element is checked, until eit
|> Seq.takeWhile (fun protein -> protein <> "STOP")
```

````exercism/note
~~~~exercism/note
One could also write the above as:
```fsharp
|> Seq.takeWhile ((<>) "STOP")
```
However, this is arguably less readable.
````
~~~~

### Converting to a list

Expand Down
20 changes: 10 additions & 10 deletions exercises/practice/protein-translation/.approaches/span/content.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,20 +45,20 @@ let rec doProteins (rna: ReadOnlySpan<char>) (proteins: string list): string lis
We'll define this function inside the `proteins` function (also known as a _nested_ function), but it could just as well have been defined outside the `proteins` function.
That said, its implementation _is_ merely a helper to the `proteins` function and is thus tied to that function, so to have it be close to where it is called often makes sense (it signals to the reader that the function should only be used _within_ its parent function).

```exercism/note
~~~~exercism/note
To allow a function to recursively call itself, the `rec` modified must be added.
In other words: by default, functions cannot call themselves.
```
~~~~

### Translating

As each codon is three letters long, the `doProteins` function looks at the first three letters of its `codons` parameter via its [`StartsWith()`][span.startswith] method.
For each translateable codon, we recursively call the `doProteins` function, with the remainder of the codons (skipping the first three letters) and the codon's protein added to the proteins accumulator value as arguments.

```exercism/note
~~~~exercism/note
We skip over the first three letters via the [`Slice()` method](https://learn.microsoft.com/en-us/dotnet/api/system.span-1.slice#system-span-1-slice(system-int32)), which does _not_ allocate a new `string` but only a new `ReadOnlySpan`.
The underlying `string` remains the same, but the _view_ of that string is offset by 3.
```
~~~~

```fsharp
if rna.StartsWith("AUG") then doProteins (rna.Slice(3)) ("Methionine" :: proteins)
Expand Down Expand Up @@ -94,11 +94,11 @@ There is one additional case we need to process, and that is when there are no c
elif rna.IsEmpty then List.rev protein
```

```exercism/note
~~~~exercism/note
We need to use [`List.rev`](https://fsharp.github.io/fsharp-core-docs/reference/fsharp-collections-listmodule.html#rev) to reverse the proteins, as translated proteins are added at the head of the list (in the front).
Prepending an element to a list is _much_ faster than appending an element.
In fact, it is so much faster that the penalty of having to reverse the list ends up being well worth it.
```
~~~~

### Unknown input

Expand Down Expand Up @@ -135,10 +135,10 @@ elif rna.IsEmpty then List.rev proteins
else failwith "Unknown coding"
```

```exercism/note
~~~~exercism/note
A downside of vertical alignment is that changes to the code require more work, as you'll need to ensure everything is still aligned.
For this particular case, it isn't really an issue, as the codons are fixed and the code is thus unlikely to change.
```
~~~~

## Putting it all together

Expand All @@ -150,12 +150,12 @@ doProteins (rna.AsSpan()) []

And with that, we have a working, tail recursive implementation that translates the RNA to proteins whilst minimizing string allocations.

```exercism/note
~~~~exercism/note
Tail recursion prevents stack overflows when a recursive function is called many times.
While the exercise does not have large test cases that would cause a stack overflow, it is good practice to always use using tail recursion when implementing a recursive functions.
If you'd like to read more about tail recursion, [this MSDN article](https://blogs.msdn.microsoft.com/fsharpteam/2011/07/08/tail-calls-in-f/) goes into more detail.
Another good resource on tail recursion is [this blog post](http://blog.ploeh.dk/2015/12/22/tail-recurse/).
```
~~~~

[span]: https://learn.microsoft.com/en-us/dotnet/api/system.span-1
[span.startswith]: https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.startswith#system-memoryextensions-startswith-1(system-span((-0))-system-readonlyspan((-0)))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,10 +135,10 @@ match rna[0..2] with
| _ -> failwith "Unknown coding"
```

```exercism/note
~~~~exercism/note
A downside of vertical alignment is that changes to the code require more work, as you'll need to ensure everything is still aligned.
For this particular case, it isn't really an issue, as the codons are fixed and the code is thus unlikely to change.
```
~~~~

### Step-by-step execution

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,10 @@ Here is what our type looks like:
type Robot = Robot of direction: Direction * position: Position
```

```exercism/note
~~~~exercism/note
Whilst not required, we name the fields of the discriminated union.
It is a good practice to do, as it can really help with readability.
```
~~~~

## Creating a robot

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,10 @@ Here is what our type looks like:
type Robot = Robot of direction: Direction * position: Position
```

```exercism/note
~~~~exercism/note
Whilst not required, we name the fields of the discriminated union.
It is a good practice to do, as it can really help with readability.
```
~~~~

## Creating a robot

Expand Down Expand Up @@ -136,10 +136,10 @@ let rec doMove (robot: Robot) (instructions: char list): Robot =

We'll define this function within the `move` function (also known as a _nested_ function), but it could just as well have been defined outside the `move` function.

```exercism/note
~~~~exercism/note
To allow a function to recursively call itself, the `rec` modified must be added.
In other words: by default, functions cannot call themselves.
```
~~~~

The first parameter of the `doMove` function is its _accumulator_ parameter: `robot`.
This parameter represents the current robot's state and is updated between the recursive function calls until we're done processing.
Expand Down
Loading

0 comments on commit e651c2d

Please sign in to comment.