Created
February 15, 2020 15:36
-
-
Save mkrzywanski/3a1969eb2cf366696e2038186d023c62 to your computer and use it in GitHub Desktop.
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
@FunctionalInterface | |
public interface TailCall<T> { | |
static <S> TailCall<S> done(S result) { | |
return new TailCall<S>() { | |
@Override | |
public TailCall<S> apply() { | |
throw new IllegalStateException("Last tailCall does not support apply method"); | |
} | |
@Override | |
public boolean isDone() { | |
return true; | |
} | |
@Override | |
public S result() { | |
return result; | |
} | |
}; | |
} | |
static <S> TailCall<S> invoke(final TailCall<S> tailCall) { | |
TailCall<S> tailCallStage = tailCall; | |
while (!tailCallStage.isDone()) { | |
tailCallStage = tailCallStage.apply(); | |
} | |
return tailCallStage; | |
} | |
TailCall<T> apply(); | |
default boolean isDone() { | |
return false; | |
} | |
default T result() { | |
throw new IllegalStateException("Intermediate tailCall does not have any result"); | |
} | |
} | |
class Factorial { | |
public static TailCall<Long> factorial(long n) { | |
return factorial(n, n - 1); | |
} | |
private static TailCall<Long> factorial(long fact, long n) { | |
if (n == 0 || n == 1) { | |
return TailCall.done(fact); | |
} else { | |
return () -> factorial(fact * n, n - 1); | |
} | |
} | |
} | |
class Test { | |
public static void main(String[] args) { | |
Long result = TailCall.invoke(Factorial.factorial(2)).result(); | |
System.out.println("Result " + result); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment