Pass a typed function as a parameter in Dart

Functional ProgrammingDart

Functional Programming Problem Overview


I know the [Function][1] class can be passed as a parameter to another function, like this:

void doSomething(Function f) {
    f(123);
}

But is there a way to constrain the arguments and the return type of the function parameter?

For instance, in this case f is being invoked directly on an integer, but what if it was a function accepting a different type?

I tried passing it as a Function<Integer>, but Function is not a parametric type.

Is there any other way to specify the signature of the function being passed as a parameter?

[1]: https://api.dartlang.org/stable/1.22.1/dart-core/Function-class.html "Function"

Functional Programming Solutions


Solution 1 - Functional Programming

Dart v1.23 added a new syntax for writing function types which also works in-line.

void doSomething(Function(int) f) {
  f(123);
}

It has the advantage over the function-parameter syntax that you can also use it for variables or anywhere else you want to write a type.

void doSomething(Function(int) f) {
  Function(int) g = f;
  g(123);
}

var x = <int Function(int)>[];

int Function(int) returnsAFunction() => (int x) => x + 1;
    
int Function(int) Function() functionValue = returnsAFunction;

Solution 2 - Functional Programming

Edit: Note that this answer contains outdated information. See Irn's answer for more up-to-date information.

Just to expand on Randal's answer, your code might look something like:

typedef void IntegerArgument(int x);

void doSomething(IntegerArgument f) {
    f(123);
}

Function<int> seems like it would be a nice idea but the problem is that we might want to specify return type as well as the type of an arbitrary number of arguments.

Solution 3 - Functional Programming

For reference.

int execute(int func(int a, int b)) => func(4, 3);

print(execute((a, b) => a + b));

Solution 4 - Functional Programming

This is what typedefs are for!

Solution 5 - Functional Programming

You can have a function typed parameter or use a typedef

void main() {
  doSomething(xToString);
  doSomething2(xToString);
}

String xToString(int s) => 's';

typedef String XToStringFn(int s);

void doSomething(String f(int s)) {
	print('value: ${f(123)}');
}

void doSomething2(XToStringFn f) {
	print('value: ${f(123)}');
}

DartPad example

Solution 6 - Functional Programming

To strongly type a function in dart do the following:

  1. Write down the Function keyword
Function
  1. Prefix it with its return type (for example void)
void Function
  1. Append it with parentheses
void Function()
  1. Put comma separated arguments inside the parentheses
void Function(int, int)
  1. Optionally - give names to your arguments
void Function(int foo, int bar)

Real life example:

void doSomething(void Function(int arg) f) {
    f(123);
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRaibazView Question on Stackoverflow
Solution 1 - Functional ProgramminglrnView Answer on Stackoverflow
Solution 2 - Functional ProgrammingRichard AmblerView Answer on Stackoverflow
Solution 3 - Functional ProgrammingJansView Answer on Stackoverflow
Solution 4 - Functional ProgrammingRandal SchwartzView Answer on Stackoverflow
Solution 5 - Functional ProgrammingGünter ZöchbauerView Answer on Stackoverflow
Solution 6 - Functional ProgrammingSound AsleepView Answer on Stackoverflow