From 1103977da8c88c57c8d831dc9455d2aaeecab9c5 Mon Sep 17 00:00:00 2001 From: Todd Schwartz Date: Wed, 22 Jul 2026 21:16:17 -0700 Subject: [PATCH 1/6] Add Flags Attribute concept exercise --- concepts/flags-attribute/.meta/config.json | 5 + concepts/flags-attribute/about.md | 51 +++++++ concepts/flags-attribute/introduction.md | 18 +++ concepts/flags-attribute/links.json | 6 + config.json | 18 +++ .../.docs/instructions.md | 37 +++++ .../.docs/introduction.md | 51 +++++++ .../.meta/Exemplar.fs | 55 ++++++++ .../.meta/config.json | 15 +++ .../ImprovedPasswordChecker.fs | 18 +++ .../ImprovedPasswordChecker.fsproj | 24 ++++ .../ImprovedPasswordCheckerTests.fs | 127 ++++++++++++++++++ 12 files changed, 425 insertions(+) create mode 100644 concepts/flags-attribute/.meta/config.json create mode 100644 concepts/flags-attribute/about.md create mode 100644 concepts/flags-attribute/introduction.md create mode 100644 concepts/flags-attribute/links.json create mode 100644 exercises/concept/improved-password-checker/.docs/instructions.md create mode 100644 exercises/concept/improved-password-checker/.docs/introduction.md create mode 100644 exercises/concept/improved-password-checker/.meta/Exemplar.fs create mode 100644 exercises/concept/improved-password-checker/.meta/config.json create mode 100644 exercises/concept/improved-password-checker/ImprovedPasswordChecker.fs create mode 100644 exercises/concept/improved-password-checker/ImprovedPasswordChecker.fsproj create mode 100644 exercises/concept/improved-password-checker/ImprovedPasswordCheckerTests.fs diff --git a/concepts/flags-attribute/.meta/config.json b/concepts/flags-attribute/.meta/config.json new file mode 100644 index 000000000..680811818 --- /dev/null +++ b/concepts/flags-attribute/.meta/config.json @@ -0,0 +1,5 @@ +{ + "blurb": "The Flags attribute allows the values defined in a discriminated union to be represented as bit positions (i.e. flags).", + "authors": ["blackk-foxx"], + "contributors": ["ErikSchierboom"] +} diff --git a/concepts/flags-attribute/about.md b/concepts/flags-attribute/about.md new file mode 100644 index 000000000..45569e0c5 --- /dev/null +++ b/concepts/flags-attribute/about.md @@ -0,0 +1,51 @@ +# About + +The Flags attribute allows the values defined in a discriminated union to be represented as bit positions (i.e. flags). +As flags, such values can be combined, making it possible for multiple boolean conditions to be represented in a single value. + +```fsharp +[] +type PhoneFeatures = +| Call = 1 +| Text = 2 +``` + +```fsharp +[] +type PhoneFeaturesBinary = +| Call = 0b00000001 +| Text = 0b00000010 +``` + +A discriminated union's cases can refer to other cases' values: + +```fsharp +[] +type PhoneFeatures = +| Call = 0b00000001 +| Text = 0b00000010 +| All = Call ||| Text +``` + +Setting a flag can be done with the bitwise OR operator (`|||`); unsetting a flag can be done with a combination of the bitwise AND operator (`&&&`) and the bitwise negation operator (`~~~`). +While checking flag's state can be done with the bitwise AND operator, one can also use the HasFlag() method. + +```fsharp +let features = PhoneFeatures.Call + +// Set the Text flag +let moreFeatures = features ||| PhoneFeatures.Text + +moreFeatures.HasFlag(PhoneFeatures.Call) // => true +moreFeatures.HasFlag(PhoneFeatures.Text) // => true + +// Unset the Call flag +let lessFeatures = features &&& ~~~PhoneFeatures.Call + +lessFeatures.HasFlag(PhoneFeatures.Call) // => false +lessFeatures.HasFlag(PhoneFeatures.Text) // => true +``` + +See [Summary of Bitwise Operators][bitwise-operators] for a complete list of the bitwise operators available in the F# language. + +[bitwise-operators]: https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/symbol-and-operator-reference/bitwise-operators#summary-of-bitwise-operators diff --git a/concepts/flags-attribute/introduction.md b/concepts/flags-attribute/introduction.md new file mode 100644 index 000000000..213f370e6 --- /dev/null +++ b/concepts/flags-attribute/introduction.md @@ -0,0 +1,18 @@ +# Introduction + +A common way to use discriminated union type in F# is to represent a fixed set of named constants -- a structure called an "enum" in other languages. + +Normally, in such a discriminated union, each case can only refer to exactly one of those named constants. +However, sometimes it is useful to refer to more than one constant. +To do so, one can annotate the discriminated union with the Flags attribute. + +A discriminated union with the Flags attribute can be defined as follows (using binary integer notation 0b): + +```fsharp +[] +type PhoneFeatures = +| Call = 0b00000001 +| Text = 0b00000010 +``` + +A `PhoneFeatures` instance with the value 0b00000011 has both its Call and Text flags set. diff --git a/concepts/flags-attribute/links.json b/concepts/flags-attribute/links.json new file mode 100644 index 000000000..501b7a945 --- /dev/null +++ b/concepts/flags-attribute/links.json @@ -0,0 +1,6 @@ +[ + { + "url": "https://learn.microsoft.com/en-us/dotnet/fundamentals/runtime-libraries/system-flagsattribute", + "description": "Flags attribute" + } +] diff --git a/config.json b/config.json index 05193524a..f3c7d2ebf 100644 --- a/config.json +++ b/config.json @@ -225,6 +225,19 @@ "basics", "pattern-matching" ] + }, + { + "slug": "improved-password-checker", + "name": "Improved Password Checker", + "uuid": "094e458d-14bc-43db-af9c-3fd951a6c635", + "concepts": [ + "flags-attribute" + ], + "prerequisites": [ + "basics", + "pattern-matching", + "results" + ] } ], "practice": [ @@ -2360,6 +2373,11 @@ "slug": "discriminated-unions", "name": "Discriminated Unions" }, + { + "uuid": "174f8c5e-e947-4e92-a0a5-1530f32b90ce", + "slug": "flags-attribute", + "name": "Flags Attribute" + }, { "uuid": "1327d780-3263-4a22-b363-684d775241b8", "slug": "floating-point-numbers", diff --git a/exercises/concept/improved-password-checker/.docs/instructions.md b/exercises/concept/improved-password-checker/.docs/instructions.md new file mode 100644 index 000000000..060ddd3f7 --- /dev/null +++ b/exercises/concept/improved-password-checker/.docs/instructions.md @@ -0,0 +1,37 @@ +The goal of this exercise is to improve upon the Password Checker exercise. +Since a given password will likely violate more than one rule at a time, a useful password checker ought to communicate to the user all the rules that are violated, instead of just the first one that happens to be discovered. +The improved password checker should indicate all of the rules being violated by a given password in one go. + +The rules for this password checker are the same as in the previous Password Checker exercise: + +- Must have 12 or more characters +- Must have at least one uppercase letter +- Must have at least one lowercase letter +- Must have at least one digit +- Must have at least one symbol in the set !@#$%^&\* + +Your solution must use a `Result` to encapsulate the success or failure status. +For the success case, the `Result` must convey the validated password as a string. +For the failure case, the `Result` must indicate all of the violated rules. + +## 1. Modify the `PasswordError` discriminated union to allow the individual values to be treated as flags + +Note that the tests will not compile until this essential step is complete. + +## 2. Implement the `checkPassword` function + +The `checkPassword` function checks the given password against the aforementioned rules. On failure, it indicates the rule(s) that was/were violated by encapsulating one or more of the `PasswordError` values within the result value. + +```fsharp +checkPassword "abcdefghijk5" +// => Error (PasswordError.MissingUppercaseLetter ||| PasswordError.MissingSymbol) +``` + +## 3. Implement the ``getStatusPhrases` function + +The `getStatusPhrases` function returns a set of strings each containing a human-readable phrase corresponding to one of the erorrs in the result returned from `checkPassword`. + +```fsharp +getStatusPhrases (Error PasswordError.MissingDigit ||| PasswordError.LessThan12Characters) +// => Set ["12 characters"; "digit"] +``` diff --git a/exercises/concept/improved-password-checker/.docs/introduction.md b/exercises/concept/improved-password-checker/.docs/introduction.md new file mode 100644 index 000000000..6e00fd6b2 --- /dev/null +++ b/exercises/concept/improved-password-checker/.docs/introduction.md @@ -0,0 +1,51 @@ +# Introduction + +The Flags attribute allows the values defined in a discriminated union to be represented as bit positions (i.e. flags). +As flags, such values can be combined, making it possible for multiple boolean conditions to be represented in a single value. + +```fsharp +[] +type PhoneFeatures = +| Call = 1 +| Text = 2 +``` + +```fsharp +[] +type PhoneFeaturesBinary = +| Call = 0b00000001 +| Text = 0b00000010 +``` + +A discriminated union's cases can refer to other cases' values: + +```fsharp +[] +type PhoneFeatures = +| Call = 0b00000001 +| Text = 0b00000010 +| All = Call ||| Text +``` + +Setting a flag can be done with the bitwise OR operator (`|||`); unsetting a flag can be done with a combination of the bitwise AND operator (`&&&`) and the bitwise negation operator (`~~~`). +While checking flag's state can be done with the bitwise AND operator, one can also use the HasFlag() method. + +```fsharp +let features = PhoneFeatures.Call + +// Set the Text flag +let moreFeatures = features ||| PhoneFeatures.Text + +moreFeatures.HasFlag(PhoneFeatures.Call) // => true +moreFeatures.HasFlag(PhoneFeatures.Text) // => true + +// Unset the Call flag +let lessFeatures = features &&& ~~~PhoneFeatures.Call + +lessFeatures.HasFlag(PhoneFeatures.Call) // => false +lessFeatures.HasFlag(PhoneFeatures.Text) // => true +``` + +See [Summary of Bitwise Operators][bitwise-operators] for a complete list of the bitwise operators available in the F# language. + +[bitwise-operators]: https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/symbol-and-operator-reference/bitwise-operators#summary-of-bitwise-operators diff --git a/exercises/concept/improved-password-checker/.meta/Exemplar.fs b/exercises/concept/improved-password-checker/.meta/Exemplar.fs new file mode 100644 index 000000000..937b82167 --- /dev/null +++ b/exercises/concept/improved-password-checker/.meta/Exemplar.fs @@ -0,0 +1,55 @@ +module ImprovedPasswordChecker + +open System + +[] +type PasswordError = + | LessThan12Characters = 1 + | MissingUppercaseLetter = 2 + | MissingLowercaseLetter = 4 + | MissingDigit = 8 + | MissingSymbol = 16 + +/// Validate the given password against the rules defined in the instructions. If it meets all +/// of the rules, return a result indicating success; otherwise return a result indicating +/// failure with an error value indicating all of the rules that were violated. +let checkPassword (password: string) : Result = + let mutable errors = ( + PasswordError.LessThan12Characters ||| + PasswordError.MissingUppercaseLetter ||| + PasswordError.MissingLowercaseLetter ||| + PasswordError.MissingDigit ||| + PasswordError.MissingSymbol + ) + if password.Length >= 12 then + errors <- errors &&& ~~~PasswordError.LessThan12Characters + for (charTest, flag) in [ + (System.Char.IsUpper, PasswordError.MissingUppercaseLetter); + (System.Char.IsLower, PasswordError.MissingLowercaseLetter); + (System.Char.IsDigit, PasswordError.MissingDigit); + ((fun c -> "!@#$%^&*".Contains c), PasswordError.MissingSymbol) + ] do + if password |> String.exists charTest then + errors <- errors &&& ~~~flag + + if int errors = 0 then + Ok password + else + Error errors + +/// Return a set of human-readable phrases indicating the meaning of the given result value. +let getStatusPhrases (result: Result) : Set = + let mutable phrases: Set = Set [ ] + match result with + | Error errors -> + for (flag, phrase) in [ + (PasswordError.LessThan12Characters, "12 characters"); + (PasswordError.MissingUppercaseLetter, "uppercase letter"); + (PasswordError.MissingLowercaseLetter, "lowercase letter"); + (PasswordError.MissingDigit, "digit"); + (PasswordError.MissingSymbol, "symbol") + ] do + if errors.HasFlag(flag) then + phrases <- phrases.Add(phrase) + | Ok _ -> () + phrases diff --git a/exercises/concept/improved-password-checker/.meta/config.json b/exercises/concept/improved-password-checker/.meta/config.json new file mode 100644 index 000000000..da82f9c75 --- /dev/null +++ b/exercises/concept/improved-password-checker/.meta/config.json @@ -0,0 +1,15 @@ +{ + "authors": [], + "files": { + "solution": [ + "ImprovedPasswordChecker.fs" + ], + "test": [ + "ImprovedPasswordCheckerTests.fs" + ], + "exemplar": [ + ".meta/Exemplar.fs" + ] + }, + "blurb": "Learn how to use the Flags attribute to combine values within a discriminated union" +} diff --git a/exercises/concept/improved-password-checker/ImprovedPasswordChecker.fs b/exercises/concept/improved-password-checker/ImprovedPasswordChecker.fs new file mode 100644 index 000000000..f33798dd3 --- /dev/null +++ b/exercises/concept/improved-password-checker/ImprovedPasswordChecker.fs @@ -0,0 +1,18 @@ +module ImprovedPasswordChecker + +type PasswordError = + | LessThan12Characters + | MissingUppercaseLetter + | MissingLowercaseLetter + | MissingDigit + | MissingSymbol + +/// Validate the given password against the rules defined in the instructions. If it meets all +/// of the rules, return a result indicating success; otherwise return a result indicating +/// failure with an error value indicating all of the rules that were violated. +let checkPassword (password: string) : Result = + failwith "Please implement this function" + +/// Return a set of human-readable phrases indicating the meaning of the given result value. +let getStatusPhrases (result: Result) : Set = + failwith "Please implement this function" diff --git a/exercises/concept/improved-password-checker/ImprovedPasswordChecker.fsproj b/exercises/concept/improved-password-checker/ImprovedPasswordChecker.fsproj new file mode 100644 index 000000000..2ef9cc891 --- /dev/null +++ b/exercises/concept/improved-password-checker/ImprovedPasswordChecker.fsproj @@ -0,0 +1,24 @@ + + + + net10.0 + Exercism + + false + + + + + + + + + + + + + + + + + diff --git a/exercises/concept/improved-password-checker/ImprovedPasswordCheckerTests.fs b/exercises/concept/improved-password-checker/ImprovedPasswordCheckerTests.fs new file mode 100644 index 000000000..11e7733d7 --- /dev/null +++ b/exercises/concept/improved-password-checker/ImprovedPasswordCheckerTests.fs @@ -0,0 +1,127 @@ +module ImprovedPasswordCheckerTests + +open FsUnit.Xunit +open Xunit +open Exercism.Tests + +open ImprovedPasswordChecker + +[] +[] +let ``Error on all rules with blank password`` () = + let expected: Result = Error ( + PasswordError.LessThan12Characters ||| + PasswordError.MissingUppercaseLetter ||| + PasswordError.MissingLowercaseLetter ||| + PasswordError.MissingDigit ||| + PasswordError.MissingSymbol + ) + checkPassword "" |> should equal expected + +[] +[] +let ``Error on most of the rules with single uppercase letter`` () = + let expected: Result = Error ( + PasswordError.LessThan12Characters ||| + PasswordError.MissingLowercaseLetter ||| + PasswordError.MissingDigit ||| + PasswordError.MissingSymbol + ) + checkPassword "A" |> should equal expected + +[] +[] +let ``Error on most of the rules with eleven uppercase letters`` () = + let expected: Result = Error ( + PasswordError.LessThan12Characters ||| + PasswordError.MissingLowercaseLetter ||| + PasswordError.MissingDigit ||| + PasswordError.MissingSymbol + ) + checkPassword "ABCDEFGHIJK" |> should equal expected + +[] +[] +let ``Error on some of the rules with twelve uppercase letters`` () = + let expected: Result = Error ( + PasswordError.MissingLowercaseLetter ||| + PasswordError.MissingDigit ||| + PasswordError.MissingSymbol + ) + checkPassword "ABCDEFGHIJKL" |> should equal expected + +[] +[] +let ``Error on two rules with thirteen mixed-case letters`` () = + let expected: Result = Error ( + PasswordError.MissingDigit ||| + PasswordError.MissingSymbol + ) + checkPassword "AbCdEfGhIjKlM" |> should equal expected + +[] +[] +let ``Missing symbol error with twelve mixed-case letters and digits`` () = + let expected: Result = Error PasswordError.MissingSymbol + checkPassword "ABCDEF123ghi" |> should equal expected + +[] +[] +let ``Missing digit error with twelve mixed-case letters and symbols`` () = + let expected: Result = Error PasswordError.MissingDigit + checkPassword "ABCDEF$&*ghi" |> should equal expected + +[] +[] +let ``Ok with valid password`` () = + let password = "ABCdef123@&$" + let expected: Result = Ok password + checkPassword password |> should equal expected + +[] +[] +let ``Insufficient length`` () = + getStatusPhrases (Error PasswordError.LessThan12Characters) |> should equal (Set ["12 characters"]) + +[] +[] +let ``Insufficient length + missing uppercase letter`` () = + let givenResult = Error (PasswordError.LessThan12Characters ||| PasswordError.MissingUppercaseLetter) + let expected = Set ["12 characters"; "uppercase letter"] + getStatusPhrases givenResult |> should equal expected + +[] +[] +let ``Insufficient length + missing uppercase letter + missing lowercase letter`` () = + let givenResult = Error ( + PasswordError.LessThan12Characters ||| + PasswordError.MissingUppercaseLetter ||| + PasswordError.MissingLowercaseLetter + ) + let expected = Set ["12 characters"; "uppercase letter"; "lowercase letter"] + getStatusPhrases givenResult |> should equal expected + +[] +[] +let ``All errors except missing symbol`` () = + let givenResult = Error ( + PasswordError.LessThan12Characters ||| + PasswordError.MissingUppercaseLetter ||| + PasswordError.MissingLowercaseLetter ||| + PasswordError.MissingDigit + ) + let expected = Set ["12 characters"; "uppercase letter"; "lowercase letter"; "digit"] + getStatusPhrases givenResult |> should equal expected + +[] +[] +let ``All errors`` () = + let givenResult = Error ( + PasswordError.LessThan12Characters ||| + PasswordError.MissingUppercaseLetter ||| + PasswordError.MissingLowercaseLetter ||| + PasswordError.MissingDigit ||| + PasswordError.MissingSymbol + ) + let expected = Set ["12 characters"; "uppercase letter"; "lowercase letter"; "digit"; "symbol"] + getStatusPhrases givenResult |> should equal expected From a80fd1abd1931ef9368b5dc1b4ae9da6958553ba Mon Sep 17 00:00:00 2001 From: Todd Schwartz Date: Thu, 23 Jul 2026 08:54:06 -0700 Subject: [PATCH 2/6] Add author to config.json; add missing hints.md --- exercises/concept/improved-password-checker/.docs/hints.md | 0 exercises/concept/improved-password-checker/.meta/config.json | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 exercises/concept/improved-password-checker/.docs/hints.md diff --git a/exercises/concept/improved-password-checker/.docs/hints.md b/exercises/concept/improved-password-checker/.docs/hints.md new file mode 100644 index 000000000..e69de29bb diff --git a/exercises/concept/improved-password-checker/.meta/config.json b/exercises/concept/improved-password-checker/.meta/config.json index da82f9c75..0fa5c8952 100644 --- a/exercises/concept/improved-password-checker/.meta/config.json +++ b/exercises/concept/improved-password-checker/.meta/config.json @@ -1,5 +1,5 @@ { - "authors": [], + "authors": ["blackk-foxx"], "files": { "solution": [ "ImprovedPasswordChecker.fs" From 08b80ff2e38ffc2062201fcbd24f43a51780dff4 Mon Sep 17 00:00:00 2001 From: Todd Schwartz Date: Tue, 28 Jul 2026 08:16:28 -0700 Subject: [PATCH 3/6] Use existing flag-discriminated-unions slug --- .../.meta/config.json | 0 .../{flags-attribute => flag-discriminated-unions}/about.md | 0 .../introduction.md | 0 .../links.json | 0 config.json | 6 +++--- 5 files changed, 3 insertions(+), 3 deletions(-) rename concepts/{flags-attribute => flag-discriminated-unions}/.meta/config.json (100%) rename concepts/{flags-attribute => flag-discriminated-unions}/about.md (100%) rename concepts/{flags-attribute => flag-discriminated-unions}/introduction.md (100%) rename concepts/{flags-attribute => flag-discriminated-unions}/links.json (100%) diff --git a/concepts/flags-attribute/.meta/config.json b/concepts/flag-discriminated-unions/.meta/config.json similarity index 100% rename from concepts/flags-attribute/.meta/config.json rename to concepts/flag-discriminated-unions/.meta/config.json diff --git a/concepts/flags-attribute/about.md b/concepts/flag-discriminated-unions/about.md similarity index 100% rename from concepts/flags-attribute/about.md rename to concepts/flag-discriminated-unions/about.md diff --git a/concepts/flags-attribute/introduction.md b/concepts/flag-discriminated-unions/introduction.md similarity index 100% rename from concepts/flags-attribute/introduction.md rename to concepts/flag-discriminated-unions/introduction.md diff --git a/concepts/flags-attribute/links.json b/concepts/flag-discriminated-unions/links.json similarity index 100% rename from concepts/flags-attribute/links.json rename to concepts/flag-discriminated-unions/links.json diff --git a/config.json b/config.json index f3c7d2ebf..f34440ba2 100644 --- a/config.json +++ b/config.json @@ -231,7 +231,7 @@ "name": "Improved Password Checker", "uuid": "094e458d-14bc-43db-af9c-3fd951a6c635", "concepts": [ - "flags-attribute" + "flag-discriminated-unions" ], "prerequisites": [ "basics", @@ -2375,8 +2375,8 @@ }, { "uuid": "174f8c5e-e947-4e92-a0a5-1530f32b90ce", - "slug": "flags-attribute", - "name": "Flags Attribute" + "slug": "flag-discriminated-unions", + "name": "Flag Discriminated Unions" }, { "uuid": "1327d780-3263-4a22-b363-684d775241b8", From cec664df4cee5ca4c888bb4d94050697fa3faf9b Mon Sep 17 00:00:00 2001 From: Todd Schwartz Date: Tue, 28 Jul 2026 08:29:53 -0700 Subject: [PATCH 4/6] Correct formatting --- config.json | 8 ++++---- .../concept/improved-password-checker/.meta/config.json | 4 +++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/config.json b/config.json index f34440ba2..722f4d6f0 100644 --- a/config.json +++ b/config.json @@ -231,12 +231,12 @@ "name": "Improved Password Checker", "uuid": "094e458d-14bc-43db-af9c-3fd951a6c635", "concepts": [ - "flag-discriminated-unions" + "flag-discriminated-unions" ], "prerequisites": [ - "basics", - "pattern-matching", - "results" + "basics", + "pattern-matching", + "results" ] } ], diff --git a/exercises/concept/improved-password-checker/.meta/config.json b/exercises/concept/improved-password-checker/.meta/config.json index 0fa5c8952..9fe26a8e8 100644 --- a/exercises/concept/improved-password-checker/.meta/config.json +++ b/exercises/concept/improved-password-checker/.meta/config.json @@ -1,5 +1,7 @@ { - "authors": ["blackk-foxx"], + "authors": [ + "blackk-foxx" + ], "files": { "solution": [ "ImprovedPasswordChecker.fs" From 8a197fc2f4dfdb480ee383cb933185217effbb9e Mon Sep 17 00:00:00 2001 From: Todd Schwartz Date: Tue, 28 Jul 2026 08:35:53 -0700 Subject: [PATCH 5/6] Add exercise ref to Exercises.slnx --- exercises/Exercises.slnx | 1 + 1 file changed, 1 insertion(+) diff --git a/exercises/Exercises.slnx b/exercises/Exercises.slnx index c25398833..12e80692e 100644 --- a/exercises/Exercises.slnx +++ b/exercises/Exercises.slnx @@ -6,6 +6,7 @@ + From e19d68efb48afbe07cdb54c6c6465a3e98628e79 Mon Sep 17 00:00:00 2001 From: Todd Schwartz Date: Tue, 28 Jul 2026 16:12:39 -0700 Subject: [PATCH 6/6] Remove incorrect assertions in docs Unlike enum cases in C#, discriminated union members cannot reference other members in F#. --- concepts/flag-discriminated-unions/about.md | 10 ---------- .../improved-password-checker/.docs/introduction.md | 10 ---------- 2 files changed, 20 deletions(-) diff --git a/concepts/flag-discriminated-unions/about.md b/concepts/flag-discriminated-unions/about.md index 45569e0c5..e79b026cd 100644 --- a/concepts/flag-discriminated-unions/about.md +++ b/concepts/flag-discriminated-unions/about.md @@ -17,16 +17,6 @@ type PhoneFeaturesBinary = | Text = 0b00000010 ``` -A discriminated union's cases can refer to other cases' values: - -```fsharp -[] -type PhoneFeatures = -| Call = 0b00000001 -| Text = 0b00000010 -| All = Call ||| Text -``` - Setting a flag can be done with the bitwise OR operator (`|||`); unsetting a flag can be done with a combination of the bitwise AND operator (`&&&`) and the bitwise negation operator (`~~~`). While checking flag's state can be done with the bitwise AND operator, one can also use the HasFlag() method. diff --git a/exercises/concept/improved-password-checker/.docs/introduction.md b/exercises/concept/improved-password-checker/.docs/introduction.md index 6e00fd6b2..2a94957b9 100644 --- a/exercises/concept/improved-password-checker/.docs/introduction.md +++ b/exercises/concept/improved-password-checker/.docs/introduction.md @@ -17,16 +17,6 @@ type PhoneFeaturesBinary = | Text = 0b00000010 ``` -A discriminated union's cases can refer to other cases' values: - -```fsharp -[] -type PhoneFeatures = -| Call = 0b00000001 -| Text = 0b00000010 -| All = Call ||| Text -``` - Setting a flag can be done with the bitwise OR operator (`|||`); unsetting a flag can be done with a combination of the bitwise AND operator (`&&&`) and the bitwise negation operator (`~~~`). While checking flag's state can be done with the bitwise AND operator, one can also use the HasFlag() method.