'Dart List.fold vs List.reduce type inference
Using Dart 2.14.2 I ran the following code
void main(List<String> args) {
var a = <int>[1, 2, 3];
final foldValue = a.fold(0, (previousValue, element) => previousValue + element);
final reduceValue = a.reduce((previousValue, element) => previousValue + element);
}
for the line containing foldValue the analyzer give me the following error :
Error: The operator '+' isn't defined for the class 'Object?'.
without giving any error for the line containing reduceValue.
My question is: what makes List.fold raises such error while List.reduce doesn't?
Solution 1:[1]
The List.fold problem is a well-known limit of the Dart type inference algorithm.
Since you haven't provided a type argument to fold, the type inference infers static type for each argument independently, then try to combine them to find a valid type argument to fold itself.
The two arguments are inferred independently and with no type hint.
The 0 argument is easy, it has type int.
The (previousValue, element) => previousValue + element function is harder.
The algorithm has no clue to what type the first parameter should be. It should be T, the type parameter of fold, but we don't know T yet. It can't use the body, because it can't type analyze the body before it has a type for the parameters (and even if it could, there are many parameter types which would make the body valid; dynamic, int, num, and double are potential candidates, and there can be more user types which allow you to add int to them.)
With no hint from the outside, the type inference uses the top-type and gets (Object? previousValue, int element) => .... Then it fails to accept previousValue + element.
The reason reduce doesn't fail is that it has all the necessary information. Both parameters must have type int, the element type of the list.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
