[SCALA] 스칼라 연속 요청을 사용하여 수율 (수율 반환)를 구현
SCALA스칼라 연속 요청을 사용하여 수율 (수율 반환)를 구현
어떻게 스칼라의 연속 요청을 사용하여 C # 수율 반환을 구현할 수 있는가? 나는 같은 스타일 스칼라 반복자를 작성할 수 있도록하고 싶습니다. 자상이 스칼라 뉴스 게시물에 코멘트에이지만 (스칼라 2.8.0 베타를 사용하여 시도) 작동하지 않습니다. 관련 질문에 대한 답변이 가능 제안,하지만 난 잠시 동안 구분 연속성을 가지고 노는 봤는데 있지만, 나는 정확히이 작업을 수행하는 방법을 주위에 내 머리를 정리하고 수없는 것.
해결법
-
==============================
1.우리가 연속성을 소개하기 전에 우리는 몇 가지 인프라를 구축 할 필요가있다. 다음은 반복 객체에 작동하는 트램 폴린이다. 반복 중 하나에 새로운 값을 얻을 수 계산하거나 그 수행 될 수있다.
우리가 연속성을 소개하기 전에 우리는 몇 가지 인프라를 구축 할 필요가있다. 다음은 반복 객체에 작동하는 트램 폴린이다. 반복 중 하나에 새로운 값을 얻을 수 계산하거나 그 수행 될 수있다.
sealed trait Iteration[+R] case class Yield[+R](result: R, next: () => Iteration[R]) extends Iteration[R] case object Done extends Iteration[Nothing] def trampoline[R](body: => Iteration[R]): Iterator[R] = { def loop(thunk: () => Iteration[R]): Stream[R] = { thunk.apply match { case Yield(result, next) => Stream.cons(result, loop(next)) case Done => Stream.empty } } loop(() => body).iterator }
트램폴린이 반복 시퀀스가 스트림 오브젝트 회전하는 내부 루프를 사용한다. 우리는 그 결과의 스트림 객체에 반복자를 호출하여 반복자를 얻을. 우리의 평가 게으른 스트림을 사용하여; 필요할 때까지 우리는 우리의 다음 반복을 평가하지 않습니다.
트램 폴린 직접 반복자를 구축하는 데 사용할 수 있습니다.
val itr1 = trampoline { Yield(1, () => Yield(2, () => Yield(3, () => Done))) } for (i <- itr1) { println(i) }
즉 그래서 우리의 반복 객체를 자동으로 생성 할 구분의 연속 요청을 사용하자, 쓰기에 꽤 끔찍한입니다.
우리는 반복으로 계산을 파괴하기 위해 변화와 리셋 연산자를 사용하여 다음 반복자에 반복을 설정하는 트램 폴린을 사용합니다.
import scala.continuations._ import scala.continuations.ControlContext.{shift,reset} def iterator[R](body: => Unit @cps[Iteration[R],Iteration[R]]): Iterator[R] = trampoline { reset[Iteration[R],Iteration[R]] { body ; Done } } def yld[R](result: R): Unit @cps[Iteration[R],Iteration[R]] = shift((k: Unit => Iteration[R]) => Yield(result, () => k(())))
이제 우리는 우리의 예를 다시 작성할 수 있습니다.
val itr2 = iterator[Int] { yld(1) yld(2) yld(3) } for (i <- itr2) { println(i) }
훨씬 낫다!
이제 여기 수율이 쇼 좀 더 고급 사용에 대한 C #을 참조 페이지에서 예입니다. 종류는 사용하기가 까다로운 약간 수 있지만 모든 작품을 할 수 있습니다.
def power(number: Int, exponent: Int): Iterator[Int] = iterator[Int] { def loop(result: Int, counter: Int): Unit @cps[Iteration[Int],Iteration[Int]] = { if (counter < exponent) { yld(result) loop(result * number, counter + 1) } } loop(number, 0) } for (i <- power(2, 8)) { println(i) }
-
==============================
2.나는 장난보다 몇 시간 후에이 작업을 수행 할 수있는 방법을 발견 할 수 있었다. 내가 나중에 않았지만 매우 리치의 및 마일의 솔루션을 주셔서 감사합니다, 이것이 내가 지금까지 본 적이 모든 다른 솔루션에 비해 주위에 내 머리를 정리하는 것이 더 간단 생각했다.
나는 장난보다 몇 시간 후에이 작업을 수행 할 수있는 방법을 발견 할 수 있었다. 내가 나중에 않았지만 매우 리치의 및 마일의 솔루션을 주셔서 감사합니다, 이것이 내가 지금까지 본 적이 모든 다른 솔루션에 비해 주위에 내 머리를 정리하는 것이 더 간단 생각했다.
def loopWhile(cond: =>Boolean)(body: =>(Unit @suspendable)): Unit @suspendable = { if (cond) { body loopWhile(cond)(body) } } class Gen { var prodCont: Unit => Unit = { x: Unit => prod } var nextVal = 0 def yld(i: Int) = shift { k: (Unit => Unit) => nextVal = i; prodCont = k } def next = { prodCont(); nextVal } def prod = { reset { // following is generator logic; can be refactored out generically var i = 0 i += 1 yld(i) i += 1 yld(i) // scala continuations plugin can't handle while loops, so need own construct loopWhile (true) { i += 1 yld(i) } } } } val it = new Gen println(it.next) println(it.next) println(it.next)
from https://stackoverflow.com/questions/2201882/implementing-yield-yield-return-using-scala-continuations by cc-by-sa and MIT license
'SCALA' 카테고리의 다른 글
[SCALA] 자바 8 스칼라의 어느 동등한이 있습니까? (0) | 2019.11.08 |
---|---|
[SCALA] scala.concurrent.blocking의 케이스를 사용하여 (0) | 2019.11.08 |
[SCALA] 속도 템플릿 리소스를 찾을 수 없습니다 (0) | 2019.11.08 |
[SCALA] 스칼라의 애플리케이션 특성과 기본 방법을 사용하여 차이점 (0) | 2019.11.08 |
[SCALA] 왜 스칼라 컴파일러 해제하면 기본 인수 방법을 오버로드는 무엇입니까? (0) | 2019.11.08 |