DART中的功能组成类型推理
在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>
然后组成ID
和list
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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这两个调用的结果是
(a a)=&gt; g(f(a))
。这不是 generic 函数,因此它不会具有任何
x function&lt;(y)
的类型y 。这是不可能的“概括性上的抽象”,而DART没有一类通用类型,因此创建适用于通用功能的一般组合将非常困难。
如果您尝试返回通用功能,则它将无法正常工作。
f
和g
的类型被进一步锁定,当a
,b
和c时/代码>类型参数。
如果您尝试要求参数函数是通用的:
它仍然无法使用,因为
b
和c
仍然在&lt的范围之外提供。 X&gt;
示例,因此它们不能依赖于x
,在您的情况下应该。真正的问题是函数类型
a function&lt; a&gt;(a)
andlist&lt; a&gt;函数&lt; a&gt;(a)
几乎与其他函数类型无关,因为定义了功能的子类型。您只能一般对待类型,如果有超模型,则可以将其视为。这就是为什么
foo&lt; t扩展了num&gt;(t x)=&gt; X.ToradixString(2);
是无效的,您必须将X
视为num
到处都是,因为这是您肯定唯一知道的事情。因此,要使作曲的工作,它需要写为:
因为这是您的实际函数参数是和的亚型的唯一一般类型在通用范围。
简而言之,不,不可能改善情况。
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 anyX
orY
.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.
The type of
f
andg
are locked further out, when theA
,B
andC
types arguments were provided.If you try to require the argument functions to be generic:
it still won't work because
B
andC
are still provided outside of the scope of the<X>
scopes, so they can't depend onX
, which they should in your case.The real issue is that the function types
A Function<A>(A)
andList<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 treatx
asnum
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:
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).