Skip to content

Commit 5d42357

Browse files
committed
Futumorphism
1 parent 2713cd1 commit 5d42357

File tree

2 files changed

+64
-0
lines changed

2 files changed

+64
-0
lines changed
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package com.jnape.palatable.lambda.recursionschemes.builtin;
2+
3+
import com.jnape.palatable.lambda.functions.Fn1;
4+
import com.jnape.palatable.lambda.functions.Fn2;
5+
import com.jnape.palatable.lambda.functor.Functor;
6+
import com.jnape.palatable.lambda.recursionschemes.Coalgebra;
7+
import com.jnape.palatable.lambda.recursionschemes.Fix;
8+
import com.jnape.palatable.lambda.recursionschemes.Free;
9+
10+
import java.util.function.Function;
11+
12+
import static com.jnape.palatable.lambda.functions.builtin.fn1.Id.id;
13+
import static com.jnape.palatable.lambda.recursionschemes.Free.pure;
14+
import static com.jnape.palatable.lambda.recursionschemes.builtin.Anamorphism.ana;
15+
16+
public final class Futumorphism<A, F extends Functor, FR extends Functor<Free<A, F, ?>, F>> implements Fn2<Function<A, FR>, A, Fix<F, ? extends Functor<? extends Fix<F, ?>, F>>> {
17+
18+
private static final Futumorphism INSTANCE = new Futumorphism();
19+
20+
private Futumorphism() {
21+
}
22+
23+
@Override
24+
@SuppressWarnings({"unchecked", "RedundantCast"})
25+
public Fix<F, ? extends Functor<? extends Fix<F, ?>, F>> apply(Function<A, FR> fn, A a) {
26+
return ana((Coalgebra<Free<A, F, ?>, FR>) free -> (FR) free.match(fn, id()), pure(a));
27+
}
28+
29+
@SuppressWarnings("unchecked")
30+
public static <A, F extends Functor, FR extends Functor<Free<A, F, ?>, F>> Futumorphism<A, F, FR> futu() {
31+
return INSTANCE;
32+
}
33+
34+
public static <A, F extends Functor, FR extends Functor<Free<A, F, ?>, F>> Fn1<A, Fix<F, ? extends Functor<? extends Fix<F, ?>, F>>> futu(
35+
Function<A, FR> fn) {
36+
return Futumorphism.<A, F, FR>futu().apply(fn);
37+
}
38+
39+
public static <A, F extends Functor, FR extends Functor<Free<A, F, ?>, F>> Fix<F, ? extends Functor<? extends Fix<F, ?>, F>> futu(
40+
Function<A, FR> fn, A a) {
41+
return futu(fn).apply(a);
42+
}
43+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package com.jnape.palatable.lambda.recursionschemes.builtin;
2+
3+
import org.junit.Test;
4+
5+
import static com.jnape.palatable.lambda.recursionschemes.Fix.fix;
6+
import static com.jnape.palatable.lambda.recursionschemes.Free.pure;
7+
import static com.jnape.palatable.lambda.recursionschemes.builtin.Futumorphism.futu;
8+
import static org.junit.Assert.assertEquals;
9+
import static testsupport.recursion.NatF.s;
10+
import static testsupport.recursion.NatF.z;
11+
12+
public class FutumorphismTest {
13+
14+
@Test
15+
public void unfoldingToGreatestFixedPointWithOptimizations() {
16+
assertEquals(fix(s(fix(s(fix(s(fix(s(fix(s(fix(z()))))))))))),
17+
futu(x -> x == 1 ? z() : x % 2 == 0
18+
? s(pure(x / 2))
19+
: s(pure(x * 3 + 1)), 5));
20+
}
21+
}

0 commit comments

Comments
 (0)