Skip to content

Commit 2713cd1

Browse files
committed
G-Apomorphism
1 parent 4c5a6d7 commit 2713cd1

File tree

3 files changed

+93
-2
lines changed

3 files changed

+93
-2
lines changed
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package com.jnape.palatable.lambda.recursionschemes.builtin;
2+
3+
import com.jnape.palatable.lambda.adt.coproduct.CoProduct2;
4+
import com.jnape.palatable.lambda.functions.Fn1;
5+
import com.jnape.palatable.lambda.functions.Fn2;
6+
import com.jnape.palatable.lambda.functions.Fn3;
7+
import com.jnape.palatable.lambda.functor.Functor;
8+
import com.jnape.palatable.lambda.recursionschemes.Coalgebra;
9+
import com.jnape.palatable.lambda.recursionschemes.Fix;
10+
11+
import java.util.function.Function;
12+
13+
import static com.jnape.palatable.lambda.recursionschemes.Fix.fix;
14+
import static com.jnape.palatable.lambda.recursionschemes.builtin.Anamorphism.ana;
15+
16+
public final class GApomorphism<A, B, F extends Functor, FT extends Functor<CoProduct2<A, B>, F>, FB extends Functor<B, F>>
17+
implements Fn3<Function<A, FT>, Coalgebra<B, FB>, A, Fix<F, Functor<Fix<F, ?>, F>>> {
18+
19+
private static final GApomorphism INSTANCE = new GApomorphism();
20+
21+
private GApomorphism() {
22+
}
23+
24+
@Override
25+
public Fix<F, Functor<Fix<F, ?>, F>> apply(Function<A, FT> fn, Coalgebra<B, FB> coalgebra, A a) {
26+
return fix(fn.apply(a).fmap((Function<CoProduct2<A, B>, Fix<F, Functor<Fix<F, ?>, F>>>)
27+
cp2 -> cp2.match(gApo(fn, coalgebra), ana(coalgebra))));
28+
}
29+
30+
@SuppressWarnings("unchecked")
31+
public static <A, B, F extends Functor, FT extends Functor<CoProduct2<A, B>, F>, FB extends Functor<B, F>> GApomorphism<A, B, F, FT, FB> gApo() {
32+
return INSTANCE;
33+
}
34+
35+
public static <A, B, F extends Functor, FT extends Functor<CoProduct2<A, B>, F>, FB extends Functor<B, F>> Fn2<Coalgebra<B, FB>, A, Fix<F, Functor<Fix<F, ?>, F>>> gApo(
36+
Function<A, FT> fn) {
37+
return GApomorphism.<A, B, F, FT, FB>gApo().apply(fn);
38+
}
39+
40+
public static <A, B, F extends Functor, FT extends Functor<CoProduct2<A, B>, F>, FB extends Functor<B, F>> Fn1<A, Fix<F, Functor<Fix<F, ?>, F>>> gApo(
41+
Function<A, FT> fn, Coalgebra<B, FB> coalgebra) {
42+
return GApomorphism.<A, B, F, FT, FB>gApo(fn).apply(coalgebra);
43+
}
44+
45+
public static <A, B, F extends Functor, FT extends Functor<CoProduct2<A, B>, F>, FB extends Functor<B, F>> Fix<F, Functor<Fix<F, ?>, F>> gApo(
46+
Function<A, FT> fn, Coalgebra<B, FB> coalgebra, A a) {
47+
return gApo(fn, coalgebra).apply(a);
48+
}
49+
}

src/test/java/com/jnape/palatable/lambda/recursionschemes/builtin/ApomorphismTest.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import com.jnape.palatable.lambda.adt.coproduct.CoProduct2;
44
import com.jnape.palatable.lambda.recursionschemes.Fix;
55
import org.junit.Test;
6+
import testsupport.recursion.ListF;
67
import testsupport.recursion.NatF;
78

89
import java.util.function.Function;
@@ -12,14 +13,21 @@
1213
import static com.jnape.palatable.lambda.recursionschemes.Fix.fix;
1314
import static com.jnape.palatable.lambda.recursionschemes.builtin.Apomorphism.apo;
1415
import static org.junit.Assert.assertEquals;
16+
import static testsupport.recursion.ListF.cons;
17+
import static testsupport.recursion.ListF.nil;
1518

1619
public class ApomorphismTest {
1720

1821
@Test
1922
public void unfoldingToGreatestFixedPointWithShortCircuit() {
20-
Function<Integer, NatF<CoProduct2<Integer, Fix<NatF, NatF<Fix<NatF, ?>>>>>> unfold =
23+
Function<Integer, NatF<CoProduct2<Integer, Fix<NatF, NatF<Fix<NatF, ?>>>>>> nats =
2124
x -> NatF.s(x < 3 ? a(x + 1) : b(fix(NatF.z())));
25+
assertEquals(Fix.<NatF, NatF<Fix<NatF, ?>>>fix(NatF.s(fix(NatF.z()))), apo(nats, 3));
26+
assertEquals(Fix.<NatF, NatF<Fix<NatF, ?>>>fix(NatF.s(fix(NatF.s(fix(NatF.s(fix(NatF.z()))))))), apo(nats, 1));
2227

23-
assertEquals(Fix.<NatF, NatF<Fix<NatF, ?>>>fix(NatF.s(fix(NatF.s(fix(NatF.s(fix(NatF.z()))))))), apo(unfold, 1));
28+
Function<Integer, ListF<String, CoProduct2<Integer, Fix<ListF<String, ?>, ListF<String, Fix<ListF<String, ?>, ?>>>>>> unfold =
29+
x -> cons("<" + x + ">", x < 3 ? a(x + 1) : b(fix(nil())));
30+
assertEquals(Fix.<ListF<String, ?>, ListF<String, Fix<ListF<String, ?>, ?>>>fix(cons("<1>", fix(cons("<2>", fix(cons("<3>", fix(nil()))))))), apo(unfold, 1));
31+
assertEquals(Fix.<ListF<String, ?>, ListF<String, Fix<ListF<String, ?>, ?>>>fix(cons("<3>", fix(nil()))), apo(unfold, 3));
2432
}
2533
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package com.jnape.palatable.lambda.recursionschemes.builtin;
2+
3+
import com.jnape.palatable.lambda.adt.coproduct.CoProduct2;
4+
import com.jnape.palatable.lambda.recursionschemes.Fix;
5+
import org.junit.Test;
6+
import testsupport.recursion.ListF;
7+
import testsupport.recursion.NatF;
8+
9+
import java.util.function.Function;
10+
11+
import static com.jnape.palatable.lambda.adt.choice.Choice2.a;
12+
import static com.jnape.palatable.lambda.adt.choice.Choice2.b;
13+
import static com.jnape.palatable.lambda.recursionschemes.Fix.fix;
14+
import static com.jnape.palatable.lambda.recursionschemes.builtin.Apomorphism.apo;
15+
import static com.jnape.palatable.lambda.recursionschemes.builtin.GApomorphism.gApo;
16+
import static org.junit.Assert.assertEquals;
17+
import static testsupport.recursion.ListF.cons;
18+
import static testsupport.recursion.ListF.nil;
19+
20+
public class GApomorphismTest {
21+
22+
@Test
23+
public void unfoldingToGreatestFixedPointWithShortCircuitAndCoalgebra() {
24+
Function<Integer, NatF<CoProduct2<Integer, Fix<NatF, NatF<Fix<NatF, ?>>>>>> nats =
25+
x -> NatF.s(x < 3 ? a(x + 1) : b(fix(NatF.z())));
26+
assertEquals(apo(nats, 3), gApo(nats, __ -> NatF.z(), 3));
27+
assertEquals(apo(nats, 1), gApo(nats, __ -> NatF.z(), 1));
28+
29+
Function<Integer, ListF<String, CoProduct2<Integer, Fix<ListF<String, ?>, ListF<String, Fix<ListF<String, ?>, ?>>>>>> unfold =
30+
x -> cons("<" + x + ">", x < 3 ? a(x + 1) : b(fix(nil())));
31+
assertEquals(apo(unfold, 1), gApo(unfold, __ -> ListF.nil(), 1));
32+
assertEquals(apo(unfold, 3), gApo(unfold, __ -> ListF.nil(), 3));
33+
}
34+
}

0 commit comments

Comments
 (0)