【发布时间】:2019-08-11 19:06:59
【问题描述】:
我想用宏构建一个枚举,包括定义它的类型参数。
有几个来源描述了使用 macros 添加枚举字段,但我还没有找到任何描述如何使用宏构建具有指定参数类型的枚举。有一个文档条目是为了限制宏 here 关于参数类型,但它仍然是空的。
这个想法是使用一个宏来生成指定数量的 Either 枚举,并增加参数类型的数量。
//Either.hx
@:build(macros.build.EitherBuildMacro.build(10))
// enum Either {} <- this isnt sufficient as we need to generated several
// enums (in this example 10 of them) with parameter types...
//And it should generate
enum Either2<A,B>{
_1(value:A);
_2(value:B);
}
enum Either3<A,B,C>{
_1(value:A);
_2(value:B);
_3(value:C);
}
enum Either4<A,B,C,D>{
_1(value:A);
_2(value:B);
_3(value:C);
_4(value:D);
}
//etc until enum Either10<A,B,C,D,E,F,G,H,I,J>
正如我在本文前面所展示的,有一篇文章描述了如何添加字段,而不是类型。我不知道如何通过宏设置这些参数类型,似乎有一些限制,但没有记录。任何用于该命令的指针都受到高度赞赏。通过增加参数化定义一系列枚举通常是您更愿意使用构建宏来完成的事情,而不是手动完成。特别是因为您可以将每个宏生成的 EitherN 与生成的宏 OneOfN abstract
相提并论
abstract OneOf2<A, B>(Either<A, B>) from Either<A, B> to Either<A, B> {
@:from inline static function fromA<A, B>(value:A):OneOf<A, B> {
return _1(a);
}
@:from inline static function fromB<A, B>(value:B):OneOf<A, B> {
return _2(b);
}
@:to inline function toA():Null<A> return switch(this) {
case _1(value): value;
default: null;
}
@:to inline function toB():Null<B> return switch(this) {
case _2(value): value;
default: null;
}
}
abstract OneOf3<A, B, C>(Either<A, B, C>) from Either<A, B, C> to Either<A, B, C> {
@:from inline static function fromA<A, B, C>(value:A):OneOf<A, B, C> {
return _1(value);
}
@:from inline static function fromB<A, B, C>(value:B):OneOf<A, B, C> {
return _2(value);
}
@:from inline static function fromC<A, B, C>(value:C):OneOf<A, B, C> {
return _3(value);
}
@:to inline function toA():Null<A> return switch(this) {
case _1(value): value;
default: null;
}
@:to inline function toB():Null<B> return switch(this) {
case _2(value): value;
default: null;
}
@:to inline function toC():Null<C> return switch(this) {
case _3(value): value;
default: null;
}
}
//etc
同样的想法可以方便地生成一系列具有越来越多参数类型的元组和函数。将是一种有效且灵活的方式来生成适量的枚举、摘要和类型定义
【问题讨论】:
-
当我完成这项工作时,我将努力更新 wiki 页面的限制并提供与食谱文章 code.haxe.org/category/other/… 相同的内容