HigherKindedTypes.java
package com.acme.collections;

import java.util.List;

import church.lang.Array;
import church.lang.ByteStream;
import church.lang.HigherKindedType;
import church.lang.operators.Streams.$$encode;
import church.primitives.Integers;
import church.primitives.Objects;
import church.util.Lists.$Get;

import static church.lang.Array.array;
import static church.lang.operators.Streams.output;
import static java.util.Arrays.asList;

@SuppressWarnings("unchecked")
public class HigherKindedTypes {
    private static final $$encode<ByteStream, String>  $S0 = Objects::$encode;
    private static final $$encode<ByteStream, Integer> $S1 = Integers::$encode;
    private static final $Get<Integer[], Integer>      $S2 = Array::get;
    private static final $Check<Integer[]>             $S3 = HigherKindedTypes.check($S2);
    private static final $Get<List<Integer>, Integer>  $S4 = HigherKindedTypes::get;
    private static final $Check<List<Integer>>         $S5 = HigherKindedTypes.check($S4);

    public static <T> T get(List<T> a, int i) {
        return a.get(i);
    }

    public static interface $Check<T> {
        public void check(@HigherKindedType("T<Integer>") T a);
    }

    public static <T> $Check<T> check($Get<T, Integer> $L0) {
        return a -> {
            int s = (($L0.get(a, 0) + $L0.get(a, 1)) + $L0.get(a, 2));
            $S0.$encode($S1.$encode($S0.$encode(output, "Sum is: "), s), "\n");
            assert s == 6;
        };
    }

    public static void main(String[] args) {
        Integer[] a = array(0, 2, 4);
        $S3.check(a);
        List<Integer> l = asList(a);
        $S5.check(l);
    }

}