Home > Software design >  Dart List.fold vs List.reduce type inferrence
Dart List.fold vs List.reduce type inferrence

Time:03-21

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?

CodePudding user response:

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 not 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.

  • Related