Skip to content

Instantly share code, notes, and snippets.

@hughsando
Created August 2, 2017 05:56
Show Gist options
  • Save hughsando/ed7caf1eaab7ab1dca47bda00f90de18 to your computer and use it in GitHub Desktop.
Save hughsando/ed7caf1eaab7ab1dca47bda00f90de18 to your computer and use it in GitHub Desktop.
Type Traits
typedef MapApi<K,V> = {
public function set(key:K,value:V) : Void;
public function get(key:K) : Null<V>;
};
@:generic
extern abstract Checker<Typedef, Instance:Typedef> (Dynamic)
{
static var instance:Instance;
inline public function new() { this = null; }
}
// Works - no Api check
typedef MyMap<K:Int,V> = haxe.ds.IntMap<V>;
// Can't have both active, although they are mutualy exclusive
//typedef MyMap<K:String,V> = haxe.ds.StringMap<V>;
//typedef MyMap<K:{},V> = haxe.ds.ObjectMap<V>;
// Api check works after the fact
typedef Check1 = Checker< MapApi<Int,Int>, MyMap<Int,Int> >;
// Fails as desired
//typedef Check2 = Checker< MapApi<Int,Int>, MyMap<Int,String> >;
// Allow combination:
// expose internal types?
//typedef MyMap<K:Int,V> = Checker< MapApi<Int,Int>, MyMap<Int,Int> >.Instance;
// or some macro exists today ?
//typedef MyMap<K:Int,V> = Tool.typeof( Checker< MapApi<Int,Int>, MyMap<Int,Int> >.instance );
class Traits
{
public static function main()
{
var t = new MyMap<Int,String>();
t.set(1,"a");
trace(t.get(1));
}
}
@hughsando
Copy link
Author

This shows how apis can be checked without inheritance. Allowing multiple typedefs, and selecting the best one allows completely different implementations to be used. With a little syntactic sugar or some macro magic, the type may be defined and checked at compile-time, with zero visibility at run-time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment