From e651c2d7b9b8df7218edd89250dee6be88396f02 Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Fri, 6 Oct 2023 10:47:40 +0200 Subject: [PATCH] Convert backtick (`) admonition fences to tildes (~). (#1197) --- concepts/tuples/about.md | 4 ++-- .../.approaches/active-patterns/content.md | 8 ++++---- .../practice/bob/.approaches/if/content.md | 8 ++++---- .../.approaches/recursion/content.md | 8 ++++---- .../sequence-expression/content.md | 4 ++-- .../.approaches/pattern-matching/content.md | 4 ++-- .../.approaches/list-comprehension/content.md | 4 ++-- .../hamming/.approaches/recursion/content.md | 8 ++++---- .../hamming/.approaches/zip/content.md | 4 ++-- .../.approaches/recursion/content.md | 16 +++++++-------- .../.approaches/seq-module/content.md | 8 ++++---- .../.approaches/span/content.md | 20 +++++++++---------- .../.approaches/unfold/content.md | 4 ++-- .../.approaches/fold/content.md | 4 ++-- .../.approaches/recursion/content.md | 8 ++++---- .../.articles/string-formatting/content.md | 8 ++++---- .../.approaches/active-patterns/content.md | 20 +++++++++---------- .../yacht/.approaches/list-module/content.md | 8 ++++---- 18 files changed, 74 insertions(+), 74 deletions(-) diff --git a/concepts/tuples/about.md b/concepts/tuples/about.md index 6097a7690..251b705b5 100644 --- a/concepts/tuples/about.md +++ b/concepts/tuples/about.md @@ -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 diff --git a/exercises/practice/bob/.approaches/active-patterns/content.md b/exercises/practice/bob/.approaches/active-patterns/content.md index bbe4a19cf..1ed3c79eb 100644 --- a/exercises/practice/bob/.approaches/active-patterns/content.md +++ b/exercises/practice/bob/.approaches/active-patterns/content.md @@ -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 @@ -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: @@ -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 diff --git a/exercises/practice/bob/.approaches/if/content.md b/exercises/practice/bob/.approaches/if/content.md index c07de4e5b..b592c92bc 100644 --- a/exercises/practice/bob/.approaches/if/content.md +++ b/exercises/practice/bob/.approaches/if/content.md @@ -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 @@ -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]: @@ -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 diff --git a/exercises/practice/collatz-conjecture/.approaches/recursion/content.md b/exercises/practice/collatz-conjecture/.approaches/recursion/content.md index ad7cdadeb..815dd9b4d 100644 --- a/exercises/practice/collatz-conjecture/.approaches/recursion/content.md +++ b/exercises/practice/collatz-conjecture/.approaches/recursion/content.md @@ -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, @@ -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 diff --git a/exercises/practice/collatz-conjecture/.approaches/sequence-expression/content.md b/exercises/practice/collatz-conjecture/.approaches/sequence-expression/content.md index 06b28e0af..c150b9e2a 100644 --- a/exercises/practice/collatz-conjecture/.approaches/sequence-expression/content.md +++ b/exercises/practice/collatz-conjecture/.approaches/sequence-expression/content.md @@ -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. diff --git a/exercises/practice/darts/.approaches/pattern-matching/content.md b/exercises/practice/darts/.approaches/pattern-matching/content.md index 173e100c4..23042cc9c 100644 --- a/exercises/practice/darts/.approaches/pattern-matching/content.md +++ b/exercises/practice/darts/.approaches/pattern-matching/content.md @@ -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: diff --git a/exercises/practice/hamming/.approaches/list-comprehension/content.md b/exercises/practice/hamming/.approaches/list-comprehension/content.md index 2b2512c9b..9258fc2f0 100644 --- a/exercises/practice/hamming/.approaches/list-comprehension/content.md +++ b/exercises/practice/hamming/.approaches/list-comprehension/content.md @@ -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 diff --git a/exercises/practice/hamming/.approaches/recursion/content.md b/exercises/practice/hamming/.approaches/recursion/content.md index 29bff9eba..047e4ebbd 100644 --- a/exercises/practice/hamming/.approaches/recursion/content.md +++ b/exercises/practice/hamming/.approaches/recursion/content.md @@ -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: @@ -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 diff --git a/exercises/practice/hamming/.approaches/zip/content.md b/exercises/practice/hamming/.approaches/zip/content.md index 6c65d7448..f4572885c 100644 --- a/exercises/practice/hamming/.approaches/zip/content.md +++ b/exercises/practice/hamming/.approaches/zip/content.md @@ -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 diff --git a/exercises/practice/protein-translation/.approaches/recursion/content.md b/exercises/practice/protein-translation/.approaches/recursion/content.md index 0f6106629..ce6e6d47c 100644 --- a/exercises/practice/protein-translation/.approaches/recursion/content.md +++ b/exercises/practice/protein-translation/.approaches/recursion/content.md @@ -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 @@ -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 @@ -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 @@ -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/). -``` +~~~~ diff --git a/exercises/practice/protein-translation/.approaches/seq-module/content.md b/exercises/practice/protein-translation/.approaches/seq-module/content.md index cd8b81f54..e1dda1165 100644 --- a/exercises/practice/protein-translation/.approaches/seq-module/content.md +++ b/exercises/practice/protein-translation/.approaches/seq-module/content.md @@ -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: @@ -170,7 +170,7 @@ 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 @@ -178,7 +178,7 @@ One could also write the above as: ``` However, this is arguably less readable. -```` +~~~~ ### Converting to a list diff --git a/exercises/practice/protein-translation/.approaches/span/content.md b/exercises/practice/protein-translation/.approaches/span/content.md index 503933bd3..837fc8420 100644 --- a/exercises/practice/protein-translation/.approaches/span/content.md +++ b/exercises/practice/protein-translation/.approaches/span/content.md @@ -45,20 +45,20 @@ let rec doProteins (rna: ReadOnlySpan) (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) @@ -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 @@ -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 @@ -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))) diff --git a/exercises/practice/protein-translation/.approaches/unfold/content.md b/exercises/practice/protein-translation/.approaches/unfold/content.md index 65e7fbd63..694896ec2 100644 --- a/exercises/practice/protein-translation/.approaches/unfold/content.md +++ b/exercises/practice/protein-translation/.approaches/unfold/content.md @@ -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 diff --git a/exercises/practice/robot-simulator/.approaches/fold/content.md b/exercises/practice/robot-simulator/.approaches/fold/content.md index 25a221ebc..7784ce651 100644 --- a/exercises/practice/robot-simulator/.approaches/fold/content.md +++ b/exercises/practice/robot-simulator/.approaches/fold/content.md @@ -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 diff --git a/exercises/practice/robot-simulator/.approaches/recursion/content.md b/exercises/practice/robot-simulator/.approaches/recursion/content.md index 4d61ef81b..132752483 100644 --- a/exercises/practice/robot-simulator/.approaches/recursion/content.md +++ b/exercises/practice/robot-simulator/.approaches/recursion/content.md @@ -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 @@ -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. diff --git a/exercises/practice/two-fer/.articles/string-formatting/content.md b/exercises/practice/two-fer/.articles/string-formatting/content.md index 77f868f9e..5617192e4 100644 --- a/exercises/practice/two-fer/.articles/string-formatting/content.md +++ b/exercises/practice/two-fer/.articles/string-formatting/content.md @@ -10,7 +10,7 @@ There are various ways in which you can format the return string. $"One for {name}, one for me."; ``` -````exercism/note +~~~~exercism/note It is possible to used typed interpolations, prefixing an interpolation with its type: ```fsharp @@ -18,7 +18,7 @@ $"One for %s{name}, one for me."; ``` This allows the compiler to check at compile time if the passed-in value has the correct type. -```` +~~~~ ## Option 2: string concatenation @@ -38,9 +38,9 @@ Before string interpolation was introduced in C# 5, [`sprintf`][sprintf] was the sprintf "One for %s, one for me.", name ``` -```exercism/note +~~~~exercism/note Unlike most other languages, a `sprintf` call in F# is type-checked at compile time, meaning you'll get a compile time error if you're passing in an incorrect value. -``` +~~~~ String interpolation is often preferred over `sprintf` for its conciseness, but `sprintf` does have the benefit of it being a function, for example enabling partial application. diff --git a/exercises/practice/yacht/.approaches/active-patterns/content.md b/exercises/practice/yacht/.approaches/active-patterns/content.md index dd2445d58..98b83d093 100644 --- a/exercises/practice/yacht/.approaches/active-patterns/content.md +++ b/exercises/practice/yacht/.approaches/active-patterns/content.md @@ -116,7 +116,7 @@ let private dieScore (die: Die): int = | Six -> 6 ``` -````exercism/note +~~~~exercism/note Another option would have been to add a member to the discriminated union: ```fsharp @@ -139,7 +139,7 @@ type Die = ``` We've chosen not to do this, as members are more awkward to use in higher-order functions, which we rely on a lot in this approach. -```` +~~~~ ## Active patterns @@ -195,10 +195,10 @@ let private (|SixesThrow|) (dice: Die list): int = |> List.length ``` -```exercism/note +~~~~exercism/note Active patterns functions have their name specified between `(|` and `|)`. This name will be used it in pattern matching, so choose the name accordingly. -``` +~~~~ The implementation is fairly straightforward. We first filter the dice matching the six dice by using [`List.filter`][list.filter]. @@ -264,9 +264,9 @@ let private (|FullHouseThrow|_|) (dice: Die list): unit option = | _ -> None ``` -```exercism/note +~~~~exercism/note We have to define the `FullHouseThrow` active pattern as a _partial_ active pattern (indicated by the `|_|` suffix), as not all dice are a full house. -``` +~~~~ #### Simplifying @@ -392,14 +392,14 @@ let private (|YachtThrow|_|) (dice: Die list): unit option = | _ -> None ``` -````exercism/note +~~~~exercism/note Alternatively, we could have counted the number of unique dice and checked if that was equal to one in an `if` expression: ```fsharp let private (|YachtThrow|_|) (dice: Die list): unit option = if List.distinct dice |> List.length = 1 then Some () else None ``` -```` +~~~~ #### Scoring @@ -419,9 +419,9 @@ We therefore don't need to define an active pattern and can just add the followi | Choice, _ -> List.sumBy dieScore dice ``` -```exercism/note +~~~~exercism/note We're matching the dice using the wildcard pattern (`_`), which will match any input. -``` +~~~~ ## Handling non-matching dice diff --git a/exercises/practice/yacht/.approaches/list-module/content.md b/exercises/practice/yacht/.approaches/list-module/content.md index 6df8008a5..fbd469373 100644 --- a/exercises/practice/yacht/.approaches/list-module/content.md +++ b/exercises/practice/yacht/.approaches/list-module/content.md @@ -117,7 +117,7 @@ let private dieScore (die: Die): int = | Six -> 6 ``` -````exercism/note +~~~~exercism/note Another option would have been to add a member to the discriminated union: ```fsharp @@ -140,7 +140,7 @@ type Die = ``` We've chosen not to do this, as members are more awkward to use in higher-order functions, which we rely on a lot in this approach. -```` +~~~~ ## Scoring categories @@ -268,14 +268,14 @@ let private yachtScore (dice: Die list): int = | _ -> 0 ``` -````exercism/note +~~~~exercism/note Alternatively, we could have counted the number of unique dice and checked if that was equal to one in an `if` expression: ```fsharp let private yachtScore (dice: Die list): int = if List.distinct dice |> List.length = 1 then 50 else 0 ``` -```` +~~~~ ### Choice score