DART中的功能组成类型推理

发布于 2025-02-12 13:22:49 字数 844 浏览 1 评论 0原文

在DART中,使用仿制药,

身份函数如下:

a to a

var id = <A>(A a) => a;

a to list类型[a] /code>:

var list = <A>(A a) => [a];

现在,我有函数组成compose

var compose = 
   <A, B>(B Function(A a) f) =>
      <C>(C Function(B b) g) => 
                       (A a) => g(f(a));

c函数(a)函数(c function(b))函数&lt; a,b&gt;(b function(a))compose < /em>

然后组成IDlist

var idList = compose(id)(list);

我希望idlist的类型应为:

list&lt; a&gt;函数&lt; a&gt;(a)

但实际的类型推理是:

动态函数(Dynamic)

是否有可能改善情况?

In dart, with generics,

the identity function works as below:

a to a:

var id = <A>(A a) => a;

a to the list type [a]:

var list = <A>(A a) => [a];

Now, I have function composition compose:

var compose = 
   <A, B>(B Function(A a) f) =>
      <C>(C Function(B b) g) => 
                       (A a) => g(f(a));

C Function(A) Function(C Function(B)) Function<A, B>(B Function(A)) compose

then compose id and list

var idList = compose(id)(list);

I want the type of idList should be :

List<A> Function<A>(A)

but the actual type inference is:

dynamic Function(dynamic)

Is it possible to improve the situation?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

乖不如嘢 2025-02-19 13:22:49

这两个调用的结果是(a a)=&gt; g(f(a))

这不是 generic 函数,因此它不会具有任何x function&lt;(y)的类型y 。

这是不可能的“概括性上的抽象”,而DART没有一类通用类型,因此创建适用于通用功能的一般组合将非常困难。

如果您尝试返回通用功能,则它将无法正常工作。

var compose =   // BAD, WON'T WORK
   <A, B>(B Function(A a) f) =>
      <C>(C Function(B b) g) => 
                    <A>(A a) => g(f(a));

fg的类型被进一步锁定,当abc时/代码>类型参数。

如果您尝试要求参数函数是通用的:

var compose =   // BAD, WON'T WORK
    <B>(B Function<X>(X) f) =>
    <C>(C Function<X>(X) g) => 
                     <A>(A a) => g(f(a));

它仍然无法使用,因为bc仍然在&lt的范围之外提供。 X&gt;示例,因此它们不能依赖于x,在您的情况下应该。

真正的问题是函数类型a function&lt; a&gt;(a) and list&lt; a&gt;函数&lt; a&gt;(a)几乎与其他函数类型无关,因为定义了功能的子类型。

您只能一般对待类型,如果有超模型,则可以将其视为。这就是为什么foo&lt; t扩展了num&gt;(t x)=&gt; X.ToradixString(2);是无效的,您必须将X视为num到处都是,因为这是您肯定唯一知道的事情。

因此,要使作曲的工作,它需要写为:

var compose =   // TOO SPECIFIC
          (A Function<A>(A a) f) =>
    (List<B> Function<B>(B b) g) => 
                        <A>(A a) => g<A>(f<A>(a));

因为这是您的实际函数参数是的亚型的唯一一般类型在通用范围。

简而言之,不,不可能改善情况。

DART无法在通用类型上抽象,因此您不能做a&lt; y&gt; foo&lt; a&lt; x&gt;,y&gt;(a&lt; x&gt; f&lt; x&gt;(x x),y y y)=&gt; f&lt; y&gt;(y);,并以包含该函数类型参数的方式在通用函数的返回类型上进行抽象。
那就是可能使它起作用的事情。您仍然需要单独的撰写用于通用和非生成功能的功能(对于通用类型参数向量的每个结构)。

The result of the two invocations is (A a) => g(f(a)).

That is not a generic function, so it won't have type X Function<A>(Y) for any X or Y.

It's not possible to "abstract over genericity", and Dart does not have first class generic types, so it's going to be incredibly difficult to create a general compose that works on generic functions.

If you try just returning a generic function, it won't work.

var compose =   // BAD, WON'T WORK
   <A, B>(B Function(A a) f) =>
      <C>(C Function(B b) g) => 
                    <A>(A a) => g(f(a));

The type of f and g are locked further out, when the A, B and C types arguments were provided.

If you try to require the argument functions to be generic:

var compose =   // BAD, WON'T WORK
    <B>(B Function<X>(X) f) =>
    <C>(C Function<X>(X) g) => 
                     <A>(A a) => g(f(a));

it still won't work because B and C are still provided outside of the scope of the <X> scopes, so they can't depend on X, which they should in your case.

The real issue is that the function types A Function<A>(A) and List<A> Function<A>(A) are pretty much unrelated to every other function type, as subtyping on functions is defined.

You can only treat a type generically, if there is a supertype you can treat it as. That's why foo<T extends num>(T x) => x.toRadixString(2); is not valid, you must treat x as num everywhere, because that's the only thing you know about it for sure.

So, for the compose to work, it needs to be written as:

var compose =   // TOO SPECIFIC
          (A Function<A>(A a) f) =>
    (List<B> Function<B>(B b) g) => 
                        <A>(A a) => g<A>(f<A>(a));

because that's the only general types that your actual function arguments are subtypes of and which allows you to get the result structure you want by looking only at the generic bounds.

In short, no, it's not possible to improve the situation.

Dart cannot abstract over a generic type, so you can't do A<Y> foo<A<X>, Y>(A<X> f<X>(X x), Y y) => f<Y>(y); and have it abstract over the return types of the generic functions in a way that includes the function's type argument.
That's the thing that could potentially make it work. You'd still need separate compose functions for generic and non-generic functions (and one for each structure of generic type-parameter vector).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文