Created
April 26, 2013 09:24
-
-
Save SimonRichardson/5466034 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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))); | |
| } | |
| } | |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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>