2012-03-15 4 views
1

나는 계층 적 데이터 구조로 무언가를하고 있으며, 아래에 설명 된 것처럼 간접적 인 재귀를 사용하여이를 트래버스/분석하는 방법 그룹을 설계했습니다.스칼라는 서로 호출하는 서로 다른 메서드에 대해 꼬리 재귀를 수행 할 수 있습니까?

Unit 반환 형식과 방법 a, b, cd, 모두가 있습니다. 방법 a이 먼저 호출됩니다. 데이터에 따라 무언가를 수행 한 다음 b/c/d 중 하나를 중지하거나 호출하십시오. b, c 및 d 각각에 동일한 작업 - 각 방법은 다른 3 가지 방법 중 하나를 중지하거나 호출 할 수 있습니다. 어떤 메소드가 호출되고 그 실행 순서는 런타임까지 알 수 없으며 직접 호출하는 메소드가 없으므로 재귀가 직접적으로 드러나지 않습니다 (걱정하지 마십시오. 모든 메소드는 해당 메소드의 순환/재귀 특성을 설명하기 위해 주석 처리됩니다). 호출).

각 추가 호출 a, b, c, 또는 d에 각각의 방법으로 실행할 수있는 마지막 일이지만, 그것은 문자 그대로 각 방법의 마지막 문장이 아니다; 어느 쪽이 호출 될지를 제어하는 ​​if 또는 case 문이 있습니다.

스칼라 컴파일러는이 다중 계층 호출 체인을 분석하여 꼬리 재귀를 구현할 수 있습니까? 메소드 자체가 직접 호출하지 않기 때문입니다.

답변

4

아니요, 스칼라는 이러한 종류의 꼬리 호출 최적화를 수행 할 수 없습니다. JVM은 실제로 이것을 가능하게하지 않는다 (적어도 쉽지 않다).

그러나 인수에 따라 네 가지 경로를 사용할 수있는 함수 하나를 작성하여 직접 모방 할 수 있습니다. 컴파일러가 자동으로 그렇게 할 수는 없지만, 당신의 유스 케이스는 scala.util.control.TailCalls을 사용해야합니다. (컴파일러가 당신을 도울 수 있다면, 이런 식으로해야합니다.)

+0

나는 다음 메서드를 직접 호출하고 'Unit'을 반환하는 대신 각 메서드가 함수 작성과 같은 다음 메서드를 반환하도록하는 방법을 생각하고 있습니다. 그런 다음 높은 수준의 메서드가 다음 메서드를 실행하므로 재귀를 완전히 피할 수 있습니다. – Gigatron

+0

@Gigatron - scala.util.control.TailCalls도 마찬가지입니다. –

1

전화가 너무 깊어서 가치가 없을 수도 있습니다.

+0

그것은 단지 4 깊이가 아니며, 깊이가 임의의 수입니다. 호출 b, b가 c를 호출하면 a가 다시 호출되고, d가 호출되면 a가 호출되며 데이터가 순회 중일 때 c가 호출됩니다. – Gigatron

+0

나만인가, 아니면 링크 된 사이트가 정말로로드 될 수 있습니까? – Gigatron