来自M <a> to M<b></b></a>的地图的typedef

时间:2013-03-26 19:41:46

标签: dart

我正在为Dart学习图书馆工作,叫做&#34; dfunct&#34;并尝试传递一个函数,该函数采用Wrapped A(Ma)并在从A到B应用函数后返回Wrapped B(Mb),同时确保包装器的类型相同。

我认为这两个例子非常适合,但都会触发警告。

typedef R Func1<T, R>(T input); // <-- included for completeness but not related

typedef M<B> Lift<M extends Monad, A, B>(M<A> source, Func1<A, B> map);
typedef Mb Lift<M extends Monad, Ma extends M<A>, A, Mb extends M<B>, B>(Ma source, Func1<A, B> map);

- 我在平均时间内使用一个不那么富有表现力的变体做出了应对,但是它没有任何类型防范B&#39; M&lt; B&#39;作为来源提供,也不保护B&#39; M的结果。在实施中:

typedef M Lift<M extends Monad, A, B>(M source, Func1<A, B> map);

- 想知道是否还有另一种表达方式,我错过了吗?

1 个答案:

答案 0 :(得分:1)

这两个都不正确:

typedef M<B> Lift<M extends Monad, A, B>(M<A> source, Func1<A, B> map);
typedef Mb Lift<M extends Monad, Ma extends M<A>, A, Mb extends M<B>, B>(Ma source, Func1<A, B> map);

问题是你说M是一个类型变量,而类型变量不带类型参数。所以你不能写:

M<A>

为什么?简短的回答是M的实际值可能是Monad的子类,它没有类型参数(或者有比Monad更多的类型参数)。

所以你能表达的“最佳”类型是:

typedef R Lift<A, B, M extends Monad<A>, R extends Monad<B>>(M source, Func1<A, B> map);

我的建议是不要尝试这个。这将更容易使用:

typedef Monad<B> Lift<A, B>(Monad<A> source, Func1<A, B> map);

请注意,Dart中的类型规则足够宽松,这将允许您使用Monad的任何子类。