Skip to content

Instantly share code, notes, and snippets.

@SimonRichardson
Created April 26, 2013 09:24
Show Gist options
  • Select an option

  • Save SimonRichardson/5466034 to your computer and use it in GitHub Desktop.

Select an option

Save SimonRichardson/5466034 to your computer and use it in GitHub Desktop.
package ;
using Main.ListTypes;
using Main.Tuple2Types;
enum ListType<T> {
Nil;
Cons(head : T, tail : List<T>);
}
abstract List<T>(ListType<T>) from ListType<T> to ListType<T> {
inline function new(list : ListType<T>) {
this = list;
}
inline public function head() : T {
return switch(this) {
case Cons(value, _): value;
case Nil: null;
}
}
inline public function tail() : List<T> {
return switch (this) {
case Cons(_, value): value;
case Nil: Nil;
}
}
}
enum Tuple2Type<T1, T2> {
tuple2(t1 : T1, t2 : T2);
}
abstract Tuple2<T1, T2>(Tuple2Type<T1, T2>) from Tuple2Type<T1, T2> to Tuple2Type<T1, T2> {
inline function new(tuple : Tuple2Type<T1, T2>) {
this = tuple;
}
inline public function _1() : T1 {
return Tuple2Types._1(this);
}
inline public function _2() : T2 {
return Tuple2Types._2(this);
}
}
class Tuple2Types {
public static function _1<T1, T2>(tuple : Tuple2<T1, T2>) : T1 {
return Type.enumParameters(tuple)[0];
}
public static function _2<T1, T2>(tuple : Tuple2<T1, T2>) : T2 {
return Type.enumParameters(tuple)[1];
}
}
class ListTypes {
inline public static function head<T>(list : List<T>) : T {
return switch(list) {
case _ if(list == null): null;
case Cons(head, _): head;
case _: null;
}
}
inline public static function prepend<T>(list : List<T>, item : T) : List<T> {
var p = list;
return Cons(item, p);
}
public static function reverse<T>(list : List<T>) : List<T> {
// Note (Simon) : We do it this way because as3 gets very confused about using.
function recursive(p, stack) {
return switch(p) {
case Cons(head, tail): recursive(tail, Cons(head, stack));
case _: stack;
}
}
return recursive(list, Nil);
}
public static function size<T>(list : List<T>) : Int {
var count = 0;
var p = list;
while(nonEmpty(p)) {
count++;
p = tail(p);
}
return count;
}
inline public static function tail<T>(list : List<T>) : List<T> {
return switch(list) {
case _ if(list == null): Nil;
case Cons(_, tail): tail;
case _: Nil;
}
}
public static function zip<T1, T2>(list : List<T1>, other : List<T2>) : List<Tuple2<T1, T2>> {
var p = list;
var amount = Std.int(Math.min(size(p), size(other)));
return if (amount <= 0) {
Nil;
} else {
var stack = Nil;
for (i in 0...amount) {
var tuple : Tuple2<T1, T2> = tuple2(head(p), head(other));
stack = prepend(stack, tuple); // <--- This is the issue at hand
p = tail(p);
other = tail(other);
}
reverse(stack);
}
}
inline public static function isEmpty<T>(list : List<T>) : Bool {
var p = list;
return switch(p) {
case Cons(_, _): false;
case _: true;
};
}
inline public static function nonEmpty<T>(list : List<T>) : Bool {
var p = list;
return !isEmpty(p);
}
}
class Main {
public static function main() {
trace(Nil.prepend('A').prepend('B').prepend('C').zip(Nil.prepend(1).prepend(2).prepend(3)));
}
}
@SimonRichardson
Copy link
Copy Markdown
Author

haxe -main Main -x main

Build with the lastest svn 6483 gives the following output - BUT this worked a few revisions back.

Main.hx:120: characters 24-45 : list : List<Tuple2Type<zip.T1, zip.T2>> -> item : Tuple2Type<zip.T1, zip.T2> -> List<Tuple2Type<zip.T1, zip.T2>> should be ListType<Tuple2<zip.T1, zip.T2>> -> Tuple2<zip.T1, zip.T2> -> List<Tuple2<zip.T1, zip.T2>>
Main.hx:120: characters 24-45 : List<Tuple2Type<zip.T1, zip.T2>> should be List<Tuple2<zip.T1, zip.T2>>
Main.hx:120: characters 24-45 : Type parameters are invariant
Main.hx:120: characters 24-45 : Tuple2Type<zip.T1, zip.T2> should be Tuple2<zip.T1, zip.T2>

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