package test0023;

class Seq<E> {
	E head;
	Seq<E> tail;
	Seq() {
		this(null, null);
	}
	boolean isEmpty() {
		return this.tail == null;
	}
	Seq(E head, Seq<E> tail) {
		this.head = head;
		this.tail = tail;
	}
	<T> Seq<Pair<E,T>> zip(Seq<T> that) {
		if (this.isEmpty() || that.isEmpty())
			return new Seq<Pair<E,T>>();
		else
			return new Seq<Pair<E,T>>(
				new Pair<E,T>(this.head, that.head),
					this.tail.zip(that.tail));
	}
	@Override
	public String toString() {
		StringBuffer buffer = new StringBuffer();
		if (head != null) {
			buffer.append(head);
		}
		if (tail != null) {
			buffer.append(tail);
		}
		return String.valueOf(buffer);
	}
	public class Zipper<T> {
		Seq<Pair<E,T>> zip(Seq<T> that) {
			if (Seq.this.isEmpty() || that.isEmpty())
				return new Seq<Pair<E,T>>();
			else
				return new Seq<Pair<E,T>>(
					new Pair<E,T>(Seq.this.head, that.head),
						Seq.this.tail.zip(that.tail));
		}
	}
}
class Pair<A, B> {
	A fst;
	B snd;
	
	Pair(A a, B b) {
		this.fst = a;
		this.snd = b;
	}
	@Override
	public String toString() {
		StringBuffer buffer = new StringBuffer();
		buffer.append("(");
		buffer.append(fst);
		buffer.append(", ");
		buffer.append(snd);
		buffer.append(")");
		return String.valueOf(buffer);
	}
	@Override
	public boolean equals(Object other) {
		return other instanceof Pair &&
				equals(fst, ((Pair)other).fst) &&
				equals(snd, ((Pair)other).snd);
	}
	private boolean equals(Object x, Object y) {
		return x == null && y == null || x != null && x.equals(y);
	}
}
public class X {
	public static void main(String[] args) {
		Seq<String> strs = new Seq<String>("a", new Seq<String>("b", new Seq<String>()));
		Seq<Number> nums = new Seq<Number>(new Integer(1), new Seq<Number>(new Double(1.5), new Seq<Number>()));
		Seq<String>.Zipper<Number> zipper = strs.new Zipper<Number>();
		Seq<Pair<String,Number>> combined = zipper.zip(nums);
		System.out.println(combined);
	}
}