Skip to content
Snippets Groups Projects
Commit 3d5e994c authored by Colin DAMON's avatar Colin DAMON
Browse files

Coding monades in Java

parent d0d83d69
No related branches found
No related tags found
1 merge request!83Resolve "Java monades code"
...@@ -36,3 +36,4 @@ include: ...@@ -36,3 +36,4 @@ include:
- local: "/mastermind/.gitlab-ci.yml" - local: "/mastermind/.gitlab-ci.yml"
- local: "/try-monade/.gitlab-ci.yml" - local: "/try-monade/.gitlab-ci.yml"
- local: "/java-puzzles/.gitlab-ci.yml" - local: "/java-puzzles/.gitlab-ci.yml"
- local: "/java-monades/.gitlab-ci.yml"
package-java-monades:
variables:
PROJECT_FOLDER: "java-monades"
extends: .java
only:
refs:
- master
- merge_requests
changes:
- ".gitlab-common-ci.yml"
- "java-monades/**/*"
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<version>1.0.0</version>
<groupId>fr.ippon.kata</groupId>
<artifactId>java-parent</artifactId>
<relativePath>../java-parent</relativePath>
</parent>
<version>1.0.0-SNAPSHOT</version>
<artifactId>java-monades</artifactId>
<name>JavaMonades</name>
<developers>
<developer>
<email>gautier.difolco@gmail.com</email>
<name>Gautier DI FOLCO</name>
</developer>
<developer>
<email>cdamon@ippon.fr</email>
<name>Colin DAMON</name>
</developer>
</developers>
</project>
# Java monades
Implémentation de différents types de monades en Java
- **Auteurs** : Gautier DI FOLCO et Colin DAMON
- **Date** : 13/05/2021
- **Langage** : Java
- **Niveau** : Bon Chance
- **Replay** : [Twitch](https://www.twitch.tv/videos/1020950472)
package fr.ippon.monad;
import java.util.Optional;
import java.util.function.Function;
public class Maybe<T> {
private final Optional<T> value;
private Maybe(Optional<T> value) {
this.value = value;
}
public static <T> Maybe<T> pure(T value) {
return new Maybe<>(Optional.of(value));
}
public static <T> Maybe<T> fail() {
return new Maybe<>(Optional.empty());
}
public <U> Maybe<U> map(Function<T, U> mapper) {
return new Maybe<>(value.map(mapper));
}
public <U> Maybe<U> bind(Function<T, Maybe<U>> other) {
return value.map(other)
.orElse(Maybe.fail());
}
@Override
public String toString() {
return value.toString();
}
}
package fr.ippon.monad;
import java.util.function.Function;
public class State<S, T> {
private final Function<S, Result<S, T>> runner;
private State(Function<S, Result<S, T>> runner) {
this.runner = runner;
}
public static <S, T> State<S, T> pure(T value) {
return new State<>(state -> new Result<>(state, value));
}
public static <S> State<S, Void> set(S value) {
return new State<>(state -> new Result<>(value, null));
}
public static <S> State<S, S> get() {
return new State<>(state -> new Result<>(state, state));
}
public <U> State<S, U> bind(
Function<T, State<S, U>> binder) {
return new State<>(initial -> {
Result<S, T> result = runner.apply(initial);
return binder.apply(result.result())
.run(result.updated());
});
}
public Result<S, T> run(S initial) {
return runner.apply(initial);
}
public static record Result<S, T> (S updated, T result) {
}
}
package fr.ippon.monad;
import static org.assertj.core.api.Assertions.*;
import org.junit.jupiter.api.Test;
class MaybeTest {
@Test
void shouldMapFromIntegerToString() {
assertThat(Maybe.pure(42)
.map(String::valueOf)).usingRecursiveComparison()
.isEqualTo(Maybe.pure("42"));
}
@Test
void shouldNotMapFailedMaybe() {
assertThat(Maybe.fail()
.map(String::valueOf)).usingRecursiveComparison()
.isEqualTo(Maybe.fail());
}
@Test
void shouldBindPureToPure() {
assertThat(Maybe.pure(42)
.bind(value -> Maybe.pure(String.valueOf(value))))
.usingRecursiveComparison()
.isEqualTo(Maybe.pure("42"));
}
}
package fr.ippon.monad;
import static org.assertj.core.api.Assertions.*;
import org.junit.jupiter.api.Test;
class StateTest {
@Test
void shouldWriteSyracuseSequence() {
State<Integer, Integer> syracuse = intState()
.bind((previous) -> {
Integer next = previous % 2 == 0 ? previous / 2
: previous * 3 + 1;
return State.set(next)
.bind(dummy -> State.pure(next));
});
assertThat(syracuse.run(5))
.isEqualTo(new State.Result<>(16, 16));
}
private State<Integer, Integer> intState() {
return State.get();
}
}
...@@ -86,6 +86,10 @@ Un kata de code est un petit exercice pensé pour s'entrainer jusqu'à maitriser ...@@ -86,6 +86,10 @@ Un kata de code est un petit exercice pensé pour s'entrainer jusqu'à maitriser
- [Concurrence en Java](/java-concurrence) - [Concurrence en Java](/java-concurrence)
- [Try monade](/try-monade) - [Try monade](/try-monade)
### Bon Chance
- [Monades en java](/java-monades)
# Discussions et présentations # Discussions et présentations
- [C'est une bonne situation ça techlead ?](https://www.youtube.com/watch?v=9tOoXfOE12o) - [C'est une bonne situation ça techlead ?](https://www.youtube.com/watch?v=9tOoXfOE12o)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment