view src/test/java/fj/data/ReaderTest.java @ 0:fe80c1edf1be

add getLoop
author tatsuki
date Fri, 20 Mar 2015 21:04:03 +0900
parents
children
line wrap: on
line source

package fj.data;

import fj.F;
import fj.data.test.PropertyAssert;
import fj.test.*;
import org.junit.Test;

import static fj.F1Functions.bind;
import static fj.F1Functions.map;
import static fj.test.Arbitrary.*;
import static fj.test.Coarbitrary.coarbInteger;
import static fj.test.Property.prop;
import static fj.test.Property.property;
import static org.junit.Assert.assertTrue;

/**
 * Created by MarkPerry on 4/12/2014.
 */
public class ReaderTest {

    @Test
    public void testMap() {
        // (3 + 8) * 11
        // example taken from http://learnyouahaskell.com/for-a-few-monads-more
        int x = Reader.unit((Integer i) -> i + 3).map(i -> i * 5).f(8);
        assertTrue(x == 55);
//        System.out.println(x); // 55
    }

    @Test
    public void testFlatMap() {
        // (3 * 2) + (3 + 10)
        // example taken from http://learnyouahaskell.com/for-a-few-monads-more
        int y = (int) Reader.unit((Integer i) -> i * 2).flatMap(a -> Reader.unit((Integer i) -> i + 10).map(b -> a + b)).f(3);
//        System.out.println(y); // 19
        assertTrue(y == 19);
    }

    @Test
    public void testMapProp() {
        Property p = property(
                arbF(coarbInteger, arbInteger),
                arbF(coarbInteger, arbInteger),
                arbInteger,
                (f, g, i) -> {
                    int expected = map(f, g).f(i);
//                    System.out.println(String.format("input: %d, result: %d", i, expected));
                    return prop(expected == Reader.unit(f).map(g).f(i));
                });
        PropertyAssert.assertResult(p);
    }

    @Test
    public void testFlatMapProp() {
        Arbitrary<F<Integer, Reader<Integer, Integer>>> a = arbF(coarbInteger, arbReader());
        Property p = property(
                arbF(coarbInteger, arbInteger),
                a,
                arbInteger,
                (f, g, i) -> {
                    int expected = bind(f, j -> g.f(j).getFunction()).f(i);
//              System.out.println(String.format("input: %d, result: %d", i, expected));
                    return prop(expected == Reader.unit(f).flatMap(g).f(i));
                }
        );
        PropertyAssert.assertResult(p);
    }

    // Left identity: return a >>= f == f a
    @Test
    public void testLeftIdentity() {
        Property p = Property.property(
                arbInteger,
                arbInteger,
                arbF(coarbInteger, arbReader()),
                (i, j, f) -> {
                    int a = Reader.<Integer, Integer>constant(i).flatMap(f).f(j);
                    int b = f.f(i).f(j);
                    return prop(a == b);
                });
        PropertyAssert.assertResult(p);
    }

    // Right identity: m >>= return == m
    @Test
    public void testRightIdentity() {
        Property p = Property.property(
                arbInteger,
                arbReader(),
                (i, r2) -> {
                    return prop(r2.flatMap(a -> Reader.constant(a)).f(i) == r2.f(i));
                });
        PropertyAssert.assertResult(p);
    }

    // Associativity: (m >>= f) >>= g == m >>= (\x -> f x >>= g)
    @Test
    public void testAssociativity() {
        Property p = Property.property(
                arbInteger,
                arbReader(),
                arbF(coarbInteger, arbReader()),
                arbF(coarbInteger, arbReader()),
                (i, r, f, g) -> {
                    boolean b2 = r.flatMap(f).flatMap(g).f(i) == r.flatMap(x -> f.f(x).flatMap(g)).f(i);
                    return prop(b2);
                });
        PropertyAssert.assertResult(p);
    }

    public Arbitrary<Reader<Integer, Integer>> arbReader() {
        return Arbitrary.arbReader(coarbInteger, arbInteger);
    }


}