Skip to content

Commit 4c5a6d7

Browse files
committed
Apomorphism
1 parent 41418b0 commit 4c5a6d7

File tree

2 files changed

+66
-0
lines changed

2 files changed

+66
-0
lines changed
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
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.functor.Functor;
7+
import com.jnape.palatable.lambda.recursionschemes.Fix;
8+
9+
import java.util.function.Function;
10+
11+
import static com.jnape.palatable.lambda.functions.builtin.fn1.Id.id;
12+
import static com.jnape.palatable.lambda.recursionschemes.Fix.fix;
13+
14+
public final class Apomorphism<A, F extends Functor, FT extends Functor<? extends CoProduct2<A, ? extends Fix<F, ? extends Functor<Fix<F, ?>, F>>>, F>>
15+
implements Fn2<Function<A, FT>, A, Fix<F, Functor<Fix<F, ?>, F>>> {
16+
17+
private static final Apomorphism INSTANCE = new Apomorphism();
18+
19+
private Apomorphism() {
20+
}
21+
22+
@Override
23+
public Fix<F, Functor<Fix<F, ?>, F>> apply(Function<A, FT> fn, A a) {
24+
return fix(fn.apply(a).fmap(cp2 -> cp2.match(apo(fn), id())));
25+
}
26+
27+
@SuppressWarnings("unchecked")
28+
public static <A, F extends Functor, FT extends Functor<? extends CoProduct2<A, ? extends Fix<F, ? extends Functor<Fix<F, ?>, F>>>, F>> Apomorphism<A, F, FT> apo() {
29+
return INSTANCE;
30+
}
31+
32+
public static <A, F extends Functor, FT extends Functor<? extends CoProduct2<A, ? extends Fix<F, ? extends Functor<Fix<F, ?>, F>>>, F>> Fn1<A, Fix<F, Functor<Fix<F, ?>, F>>> apo(
33+
Function<A, FT> fn) {
34+
return Apomorphism.<A, F, FT>apo().apply(fn);
35+
}
36+
37+
public static <A, F extends Functor, FT extends Functor<? extends CoProduct2<A, ? extends Fix<F, ? extends Functor<Fix<F, ?>, F>>>, F>> Fix<F, Functor<Fix<F, ?>, F>> apo(
38+
Function<A, FT> fn, A a) {
39+
return apo(fn).apply(a);
40+
}
41+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
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.NatF;
7+
8+
import java.util.function.Function;
9+
10+
import static com.jnape.palatable.lambda.adt.choice.Choice2.a;
11+
import static com.jnape.palatable.lambda.adt.choice.Choice2.b;
12+
import static com.jnape.palatable.lambda.recursionschemes.Fix.fix;
13+
import static com.jnape.palatable.lambda.recursionschemes.builtin.Apomorphism.apo;
14+
import static org.junit.Assert.assertEquals;
15+
16+
public class ApomorphismTest {
17+
18+
@Test
19+
public void unfoldingToGreatestFixedPointWithShortCircuit() {
20+
Function<Integer, NatF<CoProduct2<Integer, Fix<NatF, NatF<Fix<NatF, ?>>>>>> unfold =
21+
x -> NatF.s(x < 3 ? a(x + 1) : b(fix(NatF.z())));
22+
23+
assertEquals(Fix.<NatF, NatF<Fix<NatF, ?>>>fix(NatF.s(fix(NatF.s(fix(NatF.s(fix(NatF.z()))))))), apo(unfold, 1));
24+
}
25+
}

0 commit comments

Comments
 (0)