FourierTest.java
package com.acme.fourier;

import church.lang.Array;
import church.lang.Array.$CreateArray;
import church.lang.Array.$WriteElementsToStream;
import church.lang.Array.$WriteEmbracedElementsToStream;
import church.lang.ByteStream;
import church.lang.JavaClasses.$Java_class;
import church.lang.operators.Arithmetic.$$prd;
import church.lang.operators.Arithmetic.$$sub;
import church.lang.operators.Arithmetic.$$sum;
import church.lang.operators.Streams.$$encode;
import church.math.Complex;
import church.primitives.Doubles;
import church.primitives.Objects;
import com.acme.fourier.Fourier.$Evens;
import com.acme.fourier.Fourier.$Odds;
import com.acme.fourier.Fourier.$Transform;
import com.acme.fourier.Fourier.$Transform_rec;

import static church.lang.operators.Streams.output;
import static church.math.Complex.*;

@SuppressWarnings("unchecked")
public class FourierTest {
    private static final $Java_class<Complex<Double>>                                                $S0  = () -> (Class<Complex<Double>>) (Object) Complex.class;
    private static final $CreateArray<Complex<Double>>                                               $S1  = Array.createArray($S0);
    private static final $$encode<ByteStream, String>                                                $S2  = Objects::$encode;
    private static final $$encode<ByteStream, Double>                                                $S3  = Doubles::$encode;
    private static final $$encode<ByteStream, Complex<Double>>                                       $S4  = Complex.$encode($S2, $S3);
    private static final $WriteElementsToStream<ByteStream, Complex<Double>>                         $S5  = Array.writeElementsToStream($S4, $S2);
    private static final $WriteEmbracedElementsToStream<ByteStream, Complex<Double>, String, String> $S6  = Array.writeEmbracedElementsToStream($S2, $S5, $S2);
    private static final $$encode<ByteStream, Complex<Double>[]>                                     $S7  = Array.$encode($S6);
    private static final $Evens<Complex<Double>>                                                     $S8  = Fourier.evens($S1);
    private static final $Odds<Complex<Double>>                                                      $S9  = Fourier.odds($S1);
    private static final $$sum<Double>                                                               $S10 = Doubles::$sum;
    private static final $$sum<Complex<Double>>                                                      $S11 = Complex.$sum($S10);
    private static final $$sub<Double>                                                               $S12 = Doubles::$sub;
    private static final $$prd<Double, Double>                                                       $S13 = Doubles::$prd;
    private static final $$prd<Complex<Double>, Complex<Double>>                                     $S14 = Complex.$prd($S12, $S13, $S10);
    private static final $Transform_rec<Complex<Double>, Complex<Double>>                            $S15 = Fourier.transform_rec($S8, $S9, $S1, $S11, $S14);
    private static final $Transform<Complex<Double>>                                                 $S16 = Fourier.transform($S15);

    public static void main(String[] args) {
        Complex<Double>[] vec = $S1.createArray(8, i -> complex(i == 1 ? 1.0 : 0.0, 0.0));
        $S2.$encode($S7.$encode($S2.$encode(output, "input: "), vec), "\n");
        Complex<Double>[] ft = $S16.transform(vec);
        $S2.$encode($S7.$encode($S2.$encode(output, "output: "), ft), "\n");
        Complex<Double> last = ft[7];
        assert ((0.707 < re(last)) && (re(last) < 0.708));
    }

}