-
Notifications
You must be signed in to change notification settings - Fork 833
Open
Labels
Feature ImprovementTheme-Simple-F#A cross-community initiative called "Simple F#", keeping people in the sweet spot of the language.A cross-community initiative called "Simple F#", keeping people in the sweet spot of the language.
Milestone
Description
Error messages on functions with generic type constraints can be quite misleading, especially when the solution is to mark a function as inline. Three different (but related) cases of poor messages are shown below:
Example 1
let averageBy (f : 'T -> ^U) (source : seq<'T>) : ^U =
let inline acc (sum, count) el = (Checked.(+) sum (f el), count + 1)
let (sum, count) = Seq.fold acc ((LanguagePrimitives.GenericZero< (^U) >), 0) source
LanguagePrimitives.DivideByInt sum countExpected behavior
Compiler warning: Checked.(+) is inferred to have default type of int rather than ^U because averageBy is not marked as inline.
Actual behavior
Compiler error on Checked.(+):
Type constraint mismatch when applying the default type 'int' for a type inference variable. The type 'int' does not support the operator 'DivideByInt' Consider adding further type constraints.
Example 2
let averageBy (f : 'T -> ^U) (source : seq<'T>) : ^U =
let acc (sum, count) el = (Checked.(+) sum (f el), count + 1)
let (sum, count) = Seq.fold acc ((LanguagePrimitives.GenericZero< (^U) >), 0) source
LanguagePrimitives.DivideByInt sum countExpected behavior
Compiler warning: Checked.(+) is inferred to have default type of int rather than ^U because averageBy and/or accare not marked as inline
Actual behavior
Compiler infers type ^U as obj without warnings or errors.
Example 3
let averageBy (f : 'T -> ^U) (source : seq<'T>) : ^U =
let inline acc (sum, count) el = (Checked.(+) sum (f el), count + 1)
let (sum, count) = Seq.fold acc ((LanguagePrimitives.GenericZero< (^U) >), 0) source
Unchecked.defaultof<_> // TODO: finish implementationExpected behavior
Compiler warning: Checked.(+) is inferred to have default type of int rather than ^U because averageBy and is not marked as inline
Actual behavior
Compiler warning on Checked.(+):
This construct causes code to be less generic than indicated by the type annotations. The type variable 'U has been constrained to be type 'int'.
smoothdeveloper, forki and TIHan
Metadata
Metadata
Assignees
Labels
Feature ImprovementTheme-Simple-F#A cross-community initiative called "Simple F#", keeping people in the sweet spot of the language.A cross-community initiative called "Simple F#", keeping people in the sweet spot of the language.
Type
Projects
Status
In Progress