Replies: 2 comments 6 replies
-
Maybe https://github.com/fsharp/fslang-suggestions/discussions would be a better place for this discussion? Anyway, I think that fsharp/fslang-suggestions#1253 would address your first "extending records" suggestion, although it wouldn't be through inheritance. Your second suggestion looks like fsharp/fslang-suggestions#11, which has been declined. |
Beta Was this translation helpful? Give feedback.
6 replies
-
Yes, this should go to suggestions repo |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Note: I'm just sharing an idea, I don't know if it's possible to be implemented or if it's worth the difficulties of implementation.
Extending Records
When a user wants to create an order the client app sends this (simplified) form model:
When an admin operator wants to create an order for a customer the admin panel client sends this (simplified) form model:
Unfortunately, there is no way to extend/inherit a base record type without going to the OOP side of the F#, ideally something like this would be nice:
The
extend
keyword would just copy the base record fields, and we would still get two separate sealed classes. Any field of the base record can be overwritten by simply reusing its name and assigning a different type to it.Type Pattern
Consider the following valid F# code:
If we want a function that would extract the
Name
out of any type that has aName
field, we would write thegetName
function, which is very ugly to look at.It would be great if we could do this for example:
which says give me any type (named or anonymous) that has a
Name
field with the typestring
.Or this:
which says give me any type (named or anonymous) that has all of the fields of the type
T0
, and possibly more without necessarily being inherited from it.In that case when I want to write a function that would validate the currency code, I could write this:
and if I want to validate order items, I could write this:
and if I want to validate the
UseWallet
for a customer, I know it must be compatible withBaseOrderFormModel
:and if I want to validate a customer for admin order creation, I know it must be a
CreateAdminOrderFormModel
:and if I want to validate a discount code, I know it must be a
CreateOrderFormModel
:and so on.
Finally, if I want to group a bunch of validation functions together and pass them to a workflow (which would then try to get the first function that would return an error), maybe I could do something like this:
The good news is that the
validateCurrency
function is not tied to any specific model so anywhere in the app that I need to validate a currency I can use this function (meaning I can include this function in any validation group as long as the model has aCurrencyCode
field ofstring
). ThevalidateUserWallet
requires a##BaseOrderFormModel
so I can happily reuse it in two different workflows with two different models (because both models extend that base type). The same goes forvalidateOrderItems
. And finally, thevalidateOrderDiscountCode
andvalidateOrderCustomer
can only be included in validation groups that have their specific required models.As you can see the 2 ideas are somewhat related to each other. I know that currently having these features are (mostly) possible if we go to the OOP side of F# (with heavy use of object inheritance) because I have done a similar approach in C#, but it would be nice if we didn't have to (going to that side kind of defeats the purpose of using F# in the first place).
Beta Was this translation helpful? Give feedback.
All reactions