-
Notifications
You must be signed in to change notification settings - Fork 104
Fix internal Id type being selected in overload resolution #633
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
Conversation
|
|
||
| // Compile tests | ||
|
|
||
| let inline mapOfGroup (key: 'T -> 'Key when 'Key : equality) (sequence: '``Collection<'T>``) : Map<'Key, '``Collection<'T>``> = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@fxdmhtt this function is kind of useful.
I already thought about grouping in the past and realized that ideally they should return non-empty collections.
Returning a map makes sense for the eager groupBy (as opposed to the lazy chunkBy), so maybe we should create an issue to discuss a function that groups into a NonEmptyMap.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand how this works.
Why can I write the correct type signature by simply making the Id redundant?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In fact, when I was writing the secondary encapsulation library, I encountered many situations where I had to delete the type signature to compile. But I thought it was caused by my weak F# ability, so I didn't report it to you.
Can you tell me what happened?
@fxdmhtt F# type inference is quite complicated when combined with overload resolution. It has a complex tie breaker algorithm that, in the middle of solving type equations attempts to find a single overload that makes more sense than the others, if that's not the case, it does more type solving before attempting again. That's why sometimes we need to create ambiguity by adding a second overload with the same kind of properties (arities, struct-ness, etc) in order to create the necessary ambiguity to prevent the tie breaker to resolve earlier to a specific overload which will take the whole type solving nowhere. Of course, the F# compiler could be improved to make this situation smarter, but it's not a trivial change.
Similar situations are encountered when your code contains type annotations, they force the compiler to take a different path and sometimes they make things worse, so believe it or not there are cases when working with those generic functions where you should let the compiler do his work. Having said this, I hope you understand that taking the type inference to the limits is not always a desirable situation, this library contains functions which should be used carefully (or not used at all), I mean the use of generic functions, especially when combined have to be really justified to overcome the type inference drawbacks. Otherwise the Extension module has lot of "normal" functions that can be used instead. |
|
So the root cause is the defects of F# itself, and we just use some "magic" to circumvent these defects. Then there is another problem: if the function signature does not have a complete type description, the API documentation and fsi files are not very standardized. If the function has a complete type description, in order to circumvent the defects of F# itself, it may be necessary to modify the underlying reference library, but this is generally impossible. It seems that the ceiling of F# is a bit low. |
|
Yes, while many people have expressed desire to have type classes in F#, I personally think that it won't change that much the current situation, but instead F# type system needs to support Higher Kinds. That would solve lot of issues and make the type system more consistent. |
|
If F# is willing to support HKT, it will be closer to Haskell. That is the classic question: Why didn't Microsoft directly introduce Haskell into .NET? So I don't think I will see that day. To be honest, I feel that Microsoft is letting F# run wild. |
|
HKT would probably not give you Haskell on .net. There are many features in Haskell... |
|
Starting with the lazy evaluation by default. |
This was described here #623