Java でチャーチ数を書いてみた(途中)

ということで,Java を勉強し直すということにして,チャーチ数を書いてみた.
色々納得がいってないので後で書き直す.

interface F {
    public Integer proc(Integer x);
}

abstract class Church {
    abstract public F proc(F f);

    public static Church ZERO = new Church() {
            public F proc(F f) {
                return new F() {
                    public Integer proc(Integer x) {
                        return x;
                    }
                };
            }
        };

    public Church inc() {
        return Church.inc(this);
    }

    public Church plus(final Church n) {
        return Church.plus(this, n);
    }

    public static Church inc(final Church n) {
        return new Church() {
            public F proc(final F f) {
                return new F() {
                    public Integer proc(Integer x) {
                        return f.proc(n.proc(f).proc(x));
                    }
                };
            }
        };
    }

    public static Church plus(final Church m, final Church n) {
        return new Church() {
            public F proc(final F f) {
                return new F() {
                    public Integer proc(Integer x) {
                        return n.proc(f).proc(m.proc(f).proc(x));
                    }
                };
            }
        };
    }
}
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;

import org.junit.runner.JUnitCore;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;

public class ChurchTest {
    private Church zero = null;
    private Church one = null;
    private Church two = null;
    private Church three = null;
    private F to_i = null;
    private Integer i_zero = null;

    @Before
    public void before() {
        this.zero = Church.ZERO;
        this.to_i = new F() {
            public Integer proc(Integer x) {
                return Integer.valueOf(x.intValue() + 1);
            }
        };
        this.one = zero.inc();
        this.two = one.inc();
        this.three = one.plus(two);
        this.i_zero = new Integer(0);
    }

    @After
    public void after() {
        this.zero = null;
        this.one = null;
        this.two = null;
        this.three = null;
        this.to_i = null;
        this.i_zero = null;
    }

    @Test
    public void testToI() {
        assertThat(this.to_i.proc(i_zero), is(new Integer(1)));
    }

    @Test
    public void testZero() {
        assertThat(to_i(this.zero), is(0));
    }

    @Test
    public void testOne() {
        assertThat(to_i(this.one), is(1));
    }

    @Test
    public void testTwo() {
        assertThat(to_i(this.two), is(2));
    }

    @Test
    public void testThree() {
        assertThat(to_i(this.three), is(3));
    }

    int to_i(Church n) {
        return n.proc(this.to_i).proc(this.i_zero).intValue();
    }

    public static void main(String[] args) {
        JUnitCore.main(ChurchTest.class.getName());
    }
}