The overall type structure and utilization in my current F# is working very well. However, I want to get some perspective if I am doing something incorrectly or following some kind of anti-pattern. I do find myself very often essentially expecting a particular type in particular logic that is pulling from a more general type that is a Discriminated Union unifying a bunch of distinct types that all follow layers of common processing.
Essentially I need particular versions of this function:
'GeneralDiscriminatedUnionType -> 'SpecificCaseType
I find myself repeating many statements like the following:
let checkPromptUpdated (PromptUpdated prompt) = prompt
This is the simplest way that I've found to this; however, every one of these has a valid compiler warning that makes sense that there could be a problem if the function is called with a different type than the expected. This is fair, but I so far have like 40 to 50 of these.
So I started trying the following out, which is actually better, because it would raise a valid exception with incorrect usage (both are the same):
let checkPromptUpdated input = match input with | PromptUpdated prompt -> prompt | _ -> invalidOp "Expecting Prompt"
let checkPromptUpdated = function | PromptUpdated prompt -> prompt | _ -> invalidOp "Expecting Prompt"
However, this looks a lot messier and I'm trying to find out if anyone has any suggestions prior to me doing this messiness all over.
Is there some way to apply this wider logic to a more general function that could then allow me to write this 50 to 100x in a cleaner and more direct and readable way?
This question is just a matter of trying to write cleaner code.
This is an example of a DU that I'm trying to write functions for to be able to pull the particular typed values from the cases:
type StateEvent =
| PromptUpdated of Prompt
| CorrectAnswerUpdated of CorrectAnswer
| DifficultyUpdated of Difficulty
| TagsUpdated of Tag list
| NotesUpdated of Notes
| AuthorUpdated of Author