我正在为Dart学习图书馆工作,叫做" dfunct"并尝试传递一个函数,该函数采用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);
- 想知道是否还有另一种表达方式,我错过了吗?
答案 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的任何子类。