Last active
January 27, 2020 20:48
-
-
Save tonivade/b86348f21d18bcfa942b70126f1f86f9 to your computer and use it in GitHub Desktop.
Tagless final in Java, Is it possible?
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import static com.github.tonivade.purefun.data.Sequence.listOf; | |
import static java.util.Objects.requireNonNull; | |
import static org.junit.jupiter.api.Assertions.assertEquals; | |
import org.junit.jupiter.api.Test; | |
import com.github.tonivade.purefun.Higher1; | |
import com.github.tonivade.purefun.Kind; | |
import com.github.tonivade.purefun.Tuple2; | |
import com.github.tonivade.purefun.Unit; | |
import com.github.tonivade.purefun.data.ImmutableList; | |
import com.github.tonivade.purefun.instances.IOInstances; | |
import com.github.tonivade.purefun.instances.StateInstances; | |
import com.github.tonivade.purefun.runtimes.ConsoleExecutor; | |
import com.github.tonivade.purefun.typeclasses.Console; | |
import com.github.tonivade.purefun.typeclasses.For; | |
import com.github.tonivade.purefun.typeclasses.Monad; | |
public class TaglessTest { | |
private final Program<Higher1<State.µ, ImmutableList<String>>> stateProgram = | |
new Program<>(StateInstances.monad(), StateInstances.console()); | |
private final Program<IO.µ> ioProgram = | |
new Program<>(IOInstances.monad(), IOInstances.console()); | |
@Test | |
public void stateInterpreter() { | |
State<ImmutableList<String>, Unit> state = stateProgram.echo().fix1(State::narrowK); | |
Tuple2<ImmutableList<String>, Unit> run = state.run(listOf("Toni")); | |
assertEquals(listOf("what's your name?", "Hello Toni"), run.get1()); | |
} | |
@Test | |
public void ioInterpreter() { | |
ConsoleExecutor executor = new ConsoleExecutor().read("Toni"); | |
executor.run(ioProgram.echo().fix1(IO::narrowK)); | |
assertEquals("what's your name?\nHello Toni\n", executor.getOutput()); | |
} | |
} | |
class Program<F extends Kind> { | |
private final Monad<F> monad; | |
private final Console<F> console; | |
Program(Monad<F> monad, Console<F> console) { | |
this.monad = requireNonNull(monad); | |
this.console = requireNonNull(console); | |
} | |
public Higher1<F, Unit> echo() { | |
return For.with(monad) | |
.andThen(this::whatsYourName) | |
.andThen(this::readName) | |
.flatMap(this::sayHello) | |
.run(); | |
} | |
private Higher1<F, Unit> whatsYourName() { | |
return console.println("what's your name?"); | |
} | |
private Higher1<F, String> readName() { | |
return console.readln(); | |
} | |
private Higher1<F, Unit> sayHello(String name) { | |
return console.println("Hello " + name); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment