Convert tail calls to kotlin
This commit is contained in:
parent
a2940286d5
commit
516603a948
|
@ -1,25 +0,0 @@
|
|||
package recursion;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface TailCall<T> {
|
||||
|
||||
TailCall<T> apply();
|
||||
|
||||
default boolean isComplete() {
|
||||
return false;
|
||||
}
|
||||
|
||||
default T result() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
default T invoke() {
|
||||
return Stream.iterate(this, TailCall::apply)
|
||||
.filter(TailCall::isComplete)
|
||||
.findFirst()
|
||||
.get()
|
||||
.result();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package recursion
|
||||
|
||||
@FunctionalInterface
|
||||
interface TailCall<T> {
|
||||
|
||||
fun isComplete() = false
|
||||
fun apply(): TailCall<T>
|
||||
fun result(): T = throw UnsupportedOperationException()
|
||||
|
||||
operator fun invoke() = generateSequence(this) { it.apply() }
|
||||
.first { it.isComplete() }
|
||||
.result()
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
package recursion;
|
||||
|
||||
public class TailCalls {
|
||||
|
||||
public static <T> TailCall<T> tailCall(TailCall<T> nextCall) {
|
||||
return nextCall;
|
||||
}
|
||||
|
||||
public static <T> TailCall<T> done(T value) {
|
||||
return new TailCall<T>() {
|
||||
|
||||
@Override
|
||||
public boolean isComplete() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T result() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TailCall<T> apply() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package recursion
|
||||
|
||||
object TailCalls {
|
||||
|
||||
@JvmStatic
|
||||
fun <T> tailCall(nextCall: () -> TailCall<T>) = object : TailCall<T> {
|
||||
override fun apply() = nextCall()
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun <T> done(value: T) = object : TailCall<T> {
|
||||
override fun isComplete() = true
|
||||
override fun result() = value
|
||||
override fun apply() = throw UnsupportedOperationException()
|
||||
}
|
||||
}
|
|
@ -8,13 +8,13 @@ class TailCallTest {
|
|||
|
||||
@Test
|
||||
fun `tailCall does not support result`() {
|
||||
val tailCall = TailCall<Any> { null }
|
||||
val tailCall = object : TailCall<Nothing?> { override fun apply() = done(null) }
|
||||
|
||||
assertThrows(UnsupportedOperationException::class.java) { tailCall.result() }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `done does not support apply`() {
|
||||
assertThrows(UnsupportedOperationException::class.java) { done<Any>(null).apply() }
|
||||
assertThrows(UnsupportedOperationException::class.java) { done(null).apply() }
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue