Skip to content

Instantly share code, notes, and snippets.

@timyates
Last active August 29, 2015 14:19
Show Gist options
  • Save timyates/55798b96137b04ced301 to your computer and use it in GitHub Desktop.
Save timyates/55798b96137b04ced301 to your computer and use it in GitHub Desktop.
Type insanity, and a non-general path to a functional FizzBuzz in Java 8
package fizzbuzz;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.IntStream;
import java.util.stream.Stream;
public class PairedFizzBuzz {
static class Pair<L,R> {
final L left;
final R right;
Pair(L left, R right) {
this.left = left;
this.right = right;
}
}
public static void main(String[] args) {
Function<Pair<Integer,Optional<String>>,Pair<Integer,Optional<String>>> id = (p) ->
new Pair<>(p.left, p.right);
Function<Pair<Integer,Optional<String>>,Pair<Integer,Optional<String>>> fizz = (p) ->
new Pair<>(p.left, Optional.of(p.right.map(s -> s + "Fizz").orElse("Fizz")));
Function<Pair<Integer,Optional<String>>,Pair<Integer,Optional<String>>> buzz = (p) ->
new Pair<>(p.left, Optional.of(p.right.map(s -> s + "Buzz").orElse("Buzz")));
List<Function<Pair<Integer, Optional<String>>, Pair<Integer, Optional<String>>>> fizzList =
Arrays.asList(id, id, fizz);
List<Function<Pair<Integer, Optional<String>>, Pair<Integer, Optional<String>>>> buzzList =
Arrays.asList(id, id, id, id, buzz);
Iterator<Function<Pair<Integer,Optional<String>>,Pair<Integer,Optional<String>>>> fizzes =
Stream.generate(() -> fizzList)
.flatMap(Collection::stream)
.iterator();
Iterator<Function<Pair<Integer,Optional<String>>,Pair<Integer,Optional<String>>>> buzzes =
Stream.generate(() -> buzzList)
.flatMap(Collection::stream)
.iterator();
IntStream.range(1, 1000)
.mapToObj(num -> new Pair<>(num, Optional.<String>empty()))
.map(p -> fizzes.next().apply(p))
.map(p -> buzzes.next().apply(p))
.map(p -> p.right.orElse(p.left.toString()))
.limit(20)
.forEach(System.out::println);
}
}
package fizzbuzz;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
public class PairedFizzBuzzV2 {
class Pair<L,R> {
public final L left;
public final R right;
Pair(L left, R right) {
this.left = left;
this.right = right;
}
}
class IntOptStringPair extends Pair<Integer,Optional<String>> {
IntOptStringPair(Integer left, Optional<String> right) {
super(left, right);
}
}
Function<IntOptStringPair,IntOptStringPair> id = p -> p;
Iterator<Function<IntOptStringPair,IntOptStringPair>> generate(int n, String output) {
return Stream.generate(() -> Stream.concat(
Stream.of(Collections.nCopies(n - 1, id)).flatMap(Collection::stream),
Stream.of(p -> new IntOptStringPair(p.left, Optional.of(p.right.map(s -> s + output).orElse(output)))))
.collect(Collectors.toList()))
.flatMap(Collection::stream)
.iterator();
}
public void run() {
Iterator<Function<IntOptStringPair,IntOptStringPair>> fizzes = generate(3, "Fizz");
Iterator<Function<IntOptStringPair,IntOptStringPair>> buzzes = generate(5, "Buzz");
IntStream.range(1, 1000)
.mapToObj(num -> new IntOptStringPair(num, Optional.<String>empty()))
.map(p -> fizzes.next().apply(p))
.map(p -> buzzes.next().apply(p))
.map(p -> p.right.orElse(p.left.toString()))
.limit(20)
.forEach(System.out::println);
}
public static void main(String[] args) {
new PairedFizzBuzz().run();
}
}
@timyates
Copy link
Author

This is so horrible, I'm not even sure it's right...

Might be a good start towards a cleaner solution though

Or just the effect of mild sunstroke

Copy link

ghost commented Apr 18, 2015

could you define a class

class IntegerAndOptionalPair extends Pair<Integer,Optional<String>> {}

and use that instead of the horrific Pair<Integer,Optional<String>>?

@timyates
Copy link
Author

Haha, yeah 😊

Copy link

ghost commented Apr 18, 2015

It's a poor man's type aliasing

@timyates
Copy link
Author

v2 (just posted here) is a bit nicer, but still hard to reason about ;-)

@ysb33r
Copy link

ysb33r commented Apr 20, 2015

@timyates You can nearly qualify as a C++ programmer 😀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment