-
Notifications
You must be signed in to change notification settings - Fork 21
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support multiple constraints on flexible types by #ILogger1 & #ILogger2
#1262
Comments
I'm not in favour of adjusting the F# 7 design further along these lines - the 'T is passed to |
@dsyme Could it be that you've misread the suggestion, since I'm not suggesting to remove generic parameter from ILogger<'T>, but rather enable the shortened syntax for the case when ILogger is not generic at all |
@Lanayx Yes, I misread. The restriction is there because the 'T is not implied when there are multiple type variables, e.g.
Which type variable does ILogger relate to? It feels like it would be inconsistent to allow it just for the single type variable case. Also, it's not just that non-generic is not allowed - it's that any non-self-referential instantiation is not allowed, so for example
is not allowed. |
@dsyme Thank you for the explanation, what about the other variant of this suggestion - to enable multiple flexible type restrictions? |
@Lanayx Interesting suggestion. I think let f (env: #ILogger1 & #ILogger2) = ... |
However it would only work in those places where flexible types are allowed, do you think that's a problem? |
@dsyme |
Ah yes, that use of So your proposal is to allow let f (env: 'T when 'T:> ILogger1 and 'T:> ILogger2) = ... to be written let f (env: #ILogger1 and #ILogger2) = ... There is a distinction here - I'm wondering if there will be other combinations, e.g. let f (env: 'T & #ILogger) = ... // yet another way to mixin `ILogger` constraint into `T` or let f (env: 'T & #ILogger1 & #ILogger2) = ... // mixin both constaints into `T` I don't think there are any variations on |
@dsyme From user perspective I'd like as little confusion as possible. & indeed looks like type intersection, so if fsharp supported it - this would be the way to go. If not - flexible types are not real types, but generic argument restrictions, so user doesn't even think about intersection types. |
Some thoughts:
I will reopen this and make a note in #600 and rename to indicate it's about |
#IZero<'T> and #IOne<'T>
#IZero<'T> and #IOne<'T>
#ILogger1 & #ILogger2
@Lanayx I'll also mark this as approved-in-principle. I'm not certain if the |
For what it’s worth, I’ve been using active patterns to get a “poor man’s” version of this for quite some time now. 👍 Though presumably, having the constraint logic “built-in” would provide benefits (eg: more optimized). So I’m definitely in favorite of seeing this limited-use intersectionality become a proper part of the language. 🚀 |
I'm closing this since merged into main. However it's worth noting that just a few days ago another solution emerged, which would probably have prevented me from creating suggestion at all if was known back then, it appears that it's possible to write let f (env: #ILogger1 :#ILogger2) = ... So as we now have 2 syntax options for doing the same thing, while |
Updated (@dsyme):
It seems reasonable to support a limited form of intersection type, e.g.
or also naming the type variable:
Since the F# 7 release there is a discrepancy between generic and non-generic restrictions, ie
allowed:
env: 'T when ILogger<'T>
not allowed
env: 'T when ILogger
Describe the solution you'd like
I propose to add support for non-generic case as well.
Describe alternatives you've considered
We can live with the old syntax
env: 'T when 'T:> ILogger
Another possible syntax (covering multiple cases) could be
env: #ILogger1 and #ILogger2
Pros and Cons
The advantages of making this adjustment to F#: this will allow to be more concise when dealing with a long list of restrictions, for example when implementing dependency injection based on the article https://bartoszsypytkowski.com/dealing-with-complex-dependency-injection-in-f/
The disadvantages of making this adjustment to F# are: one can say that this encourage type-level programming, but since this is the best (and probably the only) way to do scalable DI in F#, it's not an issue for me
Extra information
Estimated cost (XS, S, M, L, XL, XXL): S
Related suggestions: (put links to related suggestions here)
dotnet/fsharp#14477
Affidavit (please submit!)
Please tick this by placing a cross in the box:
Please tick all that apply:
For Readers
If you would like to see this issue implemented, please click the 👍 emoji on this issue. These counts are used to generally order the suggestions by engagement.
The text was updated successfully, but these errors were encountered: