Hacker News new | ask | show | jobs
by gresrun 2018 days ago
Compose can also be implemented easily:

    extension NullableExtensions<T> on T? {
      R? map<R>(R Function(T) transform) => this == null ? null : transform(this!);
    }
    
    V Function(V) compose<V>(Iterable<V Function(V)> functions) =>
        functions.reduce((composedFunction, function) {
          return (V value) => composedFunction(function(value));
        });
    
    num add3(num val) => val + 3;
    num multiplyBy10(num val) => val * 10;
    num subtract5(num val) => val - 5;
    
    final doABunchOfMath = compose([add3, subtract5, multiplyBy10]);
    final optionallyDoABunchOfMath = (num? value) => value.map(doABunchOfMath);

    doABunchOfMath(10); // 98
    optionallyDoABunchOfMath(10); // 98
    optionallyDoABunchOfMath(null); // null
The nullable syntax (${Type}?) also makes it clear to readers that this is a type which may or may not contain a value. If you don't supply the trailing '?', Dart will enforce that the value must exist at compile-time and you can write your functions without worrying about nulls sneaking in where they're unwanted.

In effect, int? is almost nearly Option<int>, except you cannot represent Option<Option<int>> with Dart's nullable syntax.

Check out https://nullsafety.dartpad.dev/ to play around with the possibilities!