package church.math; import static church.lang.operators.Arithmetic.*; import static church.lang.operators.Relational.$$equal; import static church.lang.operators.Streams.$$encode; @SuppressWarnings("unchecked") public class Complex<T> { public final T a; public final T b; public Complex(T a, T b) { this.a = a; this.b = b; } public static <T> Complex<T> complex(T a, T b) { return new Complex<>(a, b); } public static <T> T re(Complex<T> $0) { return $0.a; } public static <T> T im(Complex<T> $0) { return $0.b; } public static interface $Conjugate<T> { public Complex<T> conjugate(Complex<T> $0); } public static <T> $Conjugate<T> conjugate($$neg<T> $L0) { return $0 -> complex($0.a, $L0.$neg($0.b)); } public static <T, U> $$encode<T, Complex<U>> $encode($$encode<T, String> $L0, $$encode<T, U> $L1) { return (stream, $0) -> $L0.$encode($L1.$encode($L0.$encode($L1.$encode(stream, $0.a), " + "), $0.b), "i"); } public static <T> $$equal<Complex<T>> $equal($$equal<T> $L0) { return ($0, $1) -> ($L0.$equal($0.a, $1.a) && $L0.$equal($0.b, $1.b)); } public static <T> $$sum<Complex<T>> $sum($$sum<T> $L0) { return ($0, $1) -> complex($L0.$sum($0.a, $1.a), $L0.$sum($0.b, $1.b)); } public static <T> $$neg<Complex<T>> $neg($$neg<T> $L0) { return $0 -> complex($L0.$neg($0.a), $L0.$neg($0.b)); } public static <T, U> $$prd<Complex<T>, Complex<U>> $prd($$sub<U> $L0, $$prd<T, U> $L1, $$sum<U> $L2) { return ($0, $1) -> complex($L0.$sub($L1.$prd($0.a, $1.a), $L1.$prd($0.b, $1.b)), $L2.$sum($L1.$prd($0.a, $1.b), $L1.$prd($0.b, $1.a))); } public static <T> $$rcp<Complex<T>> $rcp($$sum<T> $L0, $$prd<T, T> $L1, $$div<T, T> $L2, $$neg<T> $L3) { return $0 -> { T d = $L0.$sum($L1.$prd($0.a, $0.a), $L1.$prd($0.b, $0.b)); return complex($L2.$div($0.a, d), $L2.$div($L3.$neg($0.b), d)); }; } public static <T> $Additive_identity<Complex<T>> additive_identity($Additive_identity<T> $L0) { return () -> complex($L0.additive_identity(), $L0.additive_identity()); } public static <T> $Multiplicative_identity<Complex<T>> multiplicative_identity($Multiplicative_identity<T> $L0, $Additive_identity<T> $L1) { return () -> complex($L0.multiplicative_identity(), $L1.additive_identity()); } }