Skip to content

Add Flags Attribute concept exercise - #1387

Open
blackk-foxx wants to merge 9 commits into
exercism:mainfrom
blackk-foxx:feature/flags-enum-concept
Open

Add Flags Attribute concept exercise#1387
blackk-foxx wants to merge 9 commits into
exercism:mainfrom
blackk-foxx:feature/flags-enum-concept

Conversation

@blackk-foxx

@blackk-foxx blackk-foxx commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Introduce the Flags Attribute (aka flags-discriminated-union) concept and provide an exercise to teach it. The exercise goal is to use the Flags attribute to build a password checker capable of reporting multiple rule violations in one call.

@github-actions

Copy link
Copy Markdown
Contributor

Hello. Thanks for opening a PR on Exercism 🙂

We ask that all changes to Exercism are discussed on our Community Forum before being opened on GitHub. To enforce this, we automatically close all PRs that are submitted. That doesn't mean your PR is rejected but that we want the initial discussion about it to happen on our forum where a wide range of key contributors across the Exercism ecosystem can weigh in.

You can use this link to copy this into a new topic on the forum. If we decide the PR is appropriate, we'll reopen it and continue with it, so please don't delete your local branch.

If you're interested in learning more about this auto-responder, please read this blog post.


Note: If this PR has been pre-approved, please link back to this PR on the forum thread and a maintainer or staff member will reopen it.

@github-actions github-actions Bot closed this Jul 23, 2026
@ErikSchierboom

Copy link
Copy Markdown
Member

I'm currently away, so I don't have time to review this right now. Regarding your question: I'm positive that we have other exercises that have the same problem. Likely the discriminated unions exercises. Maybe you could check to see if that is referenced somewhere? There might be an exclude list or something.

failwith "Please implement this function"

/// Return a set of human-readable phrases indicating the meaning of the given result value.
let getStatusPhrases (result: Result<string, PasswordError>) : Set<string> =

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is returning a Set, which means that the student has to know about sets. So either it needs to be a prerequisite, or we should use a list here (which is my preference).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

OK, I'll modify it to return a list.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done.

Comment thread exercises/concept/improved-password-checker/.docs/introduction.md Outdated
Comment thread exercises/concept/improved-password-checker/.docs/introduction.md Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I feel that there might be a more idiomatic F# solution here without using mutable. I'll try and come up with one/

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I think you're right -- probably some kind of map/filter combination. I will also try to come up with something.

Comment thread exercises/concept/improved-password-checker/.docs/instructions.md Outdated

## 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`.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

As mentioned elsewhere, I'd suggest making this a simple list.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done.

- 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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

These instructions are specific to task 2 (the other tasks don't use results), so should probably be moved to that task (and I've already added some alternative text there).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done.

Comment thread concepts/flag-discriminated-unions/introduction.md Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It might be worth adding a mention that flags can be set or unset using bitwise operators.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

It's already mentioned on line 20. Do you think additional verbiage is needed?

Comment on lines +62 to +72
[<Fact>]
[<Task(2)>]
let ``Missing symbol error with twelve mixed-case letters and digits`` () =
let expected: Result<string, PasswordError> = Error PasswordError.MissingSymbol
checkPassword "ABCDEF123ghi" |> should equal expected

[<Fact>]
[<Task(2)>]
let ``Missing digit error with twelve mixed-case letters and symbols`` () =
let expected: Result<string, PasswordError> = Error PasswordError.MissingDigit
checkPassword "ABCDEF$&*ghi" |> should equal expected

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I would start with these two tests, as that allows the student to first focus on the error-returning bit, and then build on that to add the flag setting pattern to combine values. In other words: if the student would follow the current order, these tests will likely always pass without having to do any work.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

When writing the tests, I had intended to start with the simplest test case first. After looking at it again, I think I got it backwards -- for this exercise, the simplest test case would actually be one in which an Ok result is expected, the next simplest would be one that violates a single rule, the next simplest would be one that violates two rules, etc. I will reorder them.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done.

blackk-foxx and others added 3 commits August 6, 2026 07:15
Co-authored-by: Erik Schierboom <erik_schierboom@hotmail.com>
- Return a list instead of a set from getStatusPhrases
- Order the checkPassword tests from simple to complex
- Make the exemplar more idiomatic
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants