Skip to content

Instantly share code, notes, and snippets.

@nadako
Created August 29, 2014 15:11
Show Gist options
  • Save nadako/bb3c01414916cf13a15e to your computer and use it in GitHub Desktop.
Save nadako/bb3c01414916cf13a15e to your computer and use it in GitHub Desktop.
Either type builder using new Rest feature
@:dce
@:genericBuild(EitherMacro.build())
class Either<Rest> {}
import haxe.macro.Context;
import haxe.macro.Expr;
import haxe.macro.Type;
using haxe.macro.Tools;
class EitherMacro {
static var arityMap = new Map<Int,Bool>();
static function build():ComplexType {
return switch (Context.getLocalType()) {
case TInst(_.get() => {pack: [], name: "Either"}, params):
return buildEitherType(params);
default:
throw false;
}
}
static function buildEitherType(types:Array<Type>):ComplexType {
var pos = Context.currentPos();
var arity = types.length;
if (arity < 2)
Context.fatalError("Either should only be used with 2 or more type parameters", pos);
var name = 'Either_$arity';
if (!arityMap.exists(arity)) {
var fromToTypes:Array<ComplexType> = [];
var params:Array<TypeParamDecl> = [];
for (i in 0...arity) {
var name = 'T$i';
fromToTypes.push(TPath({pack: [], name: name}));
params.push({name: name});
}
Context.defineType({
name: name,
pos: pos,
pack: [],
params: params,
kind: TDAbstract(macro : Dynamic, fromToTypes, fromToTypes),
fields: []
});
arityMap[arity] = true;
}
return TPath({pack: [], name: name, params: [for (t in types) TPType(t.toComplexType())]});
}
}
class Main {
static function main() {
var a:Either<String, Int> = 1;
var a:Either<Int, Bool> = false;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment