package com.codepoetics.octarine.functional.tuples;
import java.util.Objects;
import java.util.function.BiFunction;
import java.util.function.Function;
public final class T2<A, B> {
private final A a;
private final B b;
private T2(A a, B b) {
this.a = a;
this.b = b;
}
public static <S, A, B> Function<S, T2<A, B>> unpacker(Function<? super S, ? extends A> first,
Function<? super S, ? extends B> second) {
return s -> T2.of(first.apply(s), second.apply(s));
}
public static <A, B> TupleLens<T2<A, B>, A> first() {
return TupleLens.of(
0,
T2::getFirst,
T2::withFirst
);
}
public static <A, B> TupleLens<T2<A, B>, B> second() {
return TupleLens.of(
1,
T2::getSecond,
T2::withSecond
);
}
public static <A, B> T2<A, B> of(A a, B b) {
return new T2<>(a, b);
}
public A getFirst() {
return a;
}
public <A2> T2<A2, B> withFirst(A2 a2) {
return T2.of(a2, b);
}
public B getSecond() {
return b;
}
public <B2> T2<A, B2> withSecond(B2 b2) {
return T2.of(a, b2);
}
public <R> R pack(BiFunction<? super A, ? super B, ? extends R> f) {
return f.apply(a, b);
}
public <C> T3<A, B, C> push(C c) {
return Tuple.of(a, b, c);
}
public T2<B, T1<A>> pop() {
return Tuple.of(b, Tuple.of(a));
}
public T2<A, T1<B>> shift() {
return Tuple.of(a, Tuple.of(b));
}
public T2<B, A> swap() {
return T2.of(b, a);
}
@Override
public boolean equals(Object o) {
if (!(o instanceof T2)) {
return false;
}
T2 other = (T2) o;
return Objects.equals(a, other.a) &&
Objects.equals(b, other.b);
}
@Override
public int hashCode() {
return Objects.hash(a, b);
}
@Override
public String toString() {
return String.format("(%s, %s)", a, b);
}
}