【问题标题】:Why does the identity function break type inference of function composition in Dart?为什么恒等函数会破坏 Dart 中函数组合的类型推断?
【发布时间】:2021-10-09 20:12:45
【问题描述】:

我有一个由 3 个函数组成的函数,同时保留类型推断。请注意,我的合成函数是左关联的,因此这些函数是从左到右应用的。

D Function(A) compose3<A, B, C, D>(
        B Function(A) fa, C Function(B) fb, D Function(C) fc) =>
    (x) => fc(fb(fa(x)));

int incr(int x) => x + 1;

T id<T>(T x) => x;

以下代码按预期工作。 res 的类型被正确推断为int

void main() {
  var res = compose3(incr, incr, incr)(7);
  print('$res, ${res.runtimeType}'); // 10, int
}

但是,在中间插入id函数后,代码无法编译。

var res = compose3(incr, id, incr)(7); // error

有两个错误:

Couldn't infer type parameter 'C'.

Tried to infer 'dynamic' for 'C' which doesn't work:
  Parameter 'fc' declared as     'D Function(C)'
                 but argument is 'int Function(int)'.
The type 'dynamic' was inferred from:
  Parameter 'fb' declared as     'C Function(B)'
                 but argument is 'dynamic Function(dynamic)'.

Consider passing explicit type argument(s) to the generic.

The argument type 'int Function(int)' can't be assigned to the parameter type 'int Function(dynamic)'.

我尝试过明确指定返回类型,但没有帮助。

int res = compose3(incr, id, incr)(7); // error

以下内容使错误消失,但它违背了id 函数的目的。

T id<T extends int>(T x) => x;

此外,显式应用函数也可以。

void main() {
  var res = incr(id(incr(7)));
  print('$res, ${res.runtimeType}'); // 9, int
}

这已经在 Dartpad 中进行了测试,具有 null 安全性,Dart SDK 2.14.3。

为什么id 函数会破坏函数组合中的类型推断,我怎样才能使其按预期工作?

【问题讨论】:

  • stackoverflow.com/a/63966151id 没有明确的类型,它的类型参数不会从其他参数中推断出来,因此它最终会是id&lt;dynamic&gt;
  • @jamesdlin 看来你是对的。但是,这不是期望或预期的行为。你是说我正在尝试做的事情目前在 Dart 中是不可能的吗?或者有什么方法可以让它工作,也许用 typedef?
  • 无法推断出id的泛型;您需要明确使用id&lt;int&gt;

标签: flutter dart


【解决方案1】:

这是一个使用扩展方法的解决方案。

extension ComposeExtension on Function {
  C Function(A) pipe<A, B, C>(C Function(B) f) => (x) => f(this(x));
}

int incr(int x) => x + 1;

T id<T>(T x) => x;

void main() {
  var res = incr
    .pipe(id)
    .pipe(incr)(7);
  
  print('$res, ${res.runtimeType}'); // 9, int
}

【讨论】:

    猜你喜欢
    • 2021-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-03
    • 2023-02-17
    相关资源
    最近更新 更多