접기로 구현할 수 없습니다. 컬렉션의 모든 요소에 대해 반복적으로 반복하는 반면 tryOld
은 가끔 일찍 종료됩니다. 당신은 Stream
의 게으름을 활용하고 collectFirst
및 Try
의 관점에서 구현할 수 :
import scala.util.Try
def tryOld(string: String, original: Exception, zomOldList: List[String => Double]): Double =
zomOldList.toStream.map(x => Try(x(string))) collectFirst {
case Success(x) => x
} getOrElse (throw original)
를하지만, 원래 재귀 구현은 명확하고 더 성능이 좋은 것입니다.
편집 : 스칼라는 하스켈의 foldr
같은 게으름의 특성을 가진 foldRight
이 있다면
, 다음이 foldRight
의 관점에서 정의 할 수 있습니다 : 그러나
implicit class GiveStreamAWorkingFoldRight[A](val s: Stream[A]) extends AnyVal {
def lazyFoldRight[B](z: => B)(f: (A,() => B) => B): B =
if (s.isEmpty) z else f(s.head,() => s.tail.lazyFoldRight(z)(f))
}
def tryOld(string: String, original: Exception, zomOldList: List[String => Double]): Double =
zomOldList.toStream.lazyFoldRight(throw original) { (a, b:() => Double) =>
try {
a(string)
} catch {
case ex: Exception => b()
}
}
, 진정한 꼬리의 스칼라의 부족 -call 최적화는 b
을 호출 할 때마다 스택 오버플로를 유발할 수있는 새로운 스택 프레임을 도입한다는 것을 의미합니다.
정확하게 재귀에는 어떤 문제가 있습니까? 재귀는 재귀 적 문제를 해결하는 데 유용합니다. –
재귀는 다른 관점에서 솔루션을 보는 것만으로 작동합니다. 나는 예외를 던져 버리는 기능을 가진 것은 아마 나쁜 습관이라고 포스트 아래에 답했다. Try with Double [Double]을 사용하면 효과가 있습니다. – ferk86