Skip to content

Instantly share code, notes, and snippets.

@frabbit
Last active December 21, 2015 01:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save frabbit/6232020 to your computer and use it in GitHub Desktop.
Save frabbit/6232020 to your computer and use it in GitHub Desktop.
Builder Pattern with Phantom Types
using Main.PosBuilders;
typedef Pos = { x: Int, y:Int};
private extern class ISSET {}
private extern class UNSET {}
@:allow(Main.PosBuilders) class PosBuilder<X,Y> {
public function new (x,y) {
this.x = x;
this.y = y;
}
var x : Option<Int>;
var y : Option<Int>;
}
class PosBuilders
{
public static function setX <Y>(b:PosBuilder<UNSET, Y>, x:Int):PosBuilder<ISSET, Y>
{
return new PosBuilder(Some(x),b.y);
}
public static function setY <X>(b:PosBuilder<X, UNSET>, y:Int):PosBuilder<X, ISSET>
{
return new PosBuilder(b.x,Some(y));
}
public static function build (b:PosBuilder<ISSET, ISSET>):Pos
{
return switch [b.x, b.y] {
case [Some(x), Some(y)]: { x : x, y : y };
case _ : throw "assert";
}
}
public static function builder ():PosBuilder<UNSET, UNSET>
{
return new PosBuilder(None, None);
}
}
class Main {
public static function main () {
var myPos = PosBuilders.builder().setX(1).setY(2).build();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment