Каким образом преобразование циклов CPS в циклы и вызовы функций в контексте Shift / Rest? - PullRequest
0 голосов
/ 13 февраля 2020

Я пытаюсь обернуть голову вокруг Shift / Reset (продолжения с разделителями), я могу найти простые примеры, но когда дело доходит до Loops и Shift внутри вызова функции, я не могу понять это.

Пожалуйста, исправьте мои ниже, понимая

reset {
    // Do Something before Shifting out and giving control to the Caller
    println("Start")
    shift {
        // What to do with a given Continuation
        k => k(5)
    } + 3 // Continuation 
}

может быть преобразовано в

(k => {
    println("Start")
    k(5)
})(_ + 3)
var cont: Int => Int = null
reset {
    // Do Something before Shifting out and giving control to the Caller
    println("Start")
    shift {
        // What to do with a given Continuation
        k => { cont = k }
    } + 3 // Continuation 
}

// -------------------------
var cont: Int => Int = null
(k => {
    println("Start")
    cont = k
})(_ + 3)
reset {
    val x = 22
    if (x > 10) {
        println("Found it")
    } else {
        shift {
            k => k()
        }
        println("Not Found")
    }
}

// -------------------------
(k => {
    val x = 22
    if (x > 10) {
        println("Found it")
    } else {
        k()
    }
})(() => println("Not Found"))

My Doubt

// Example from Chapter 22 of Scala for the Impatient
var cont: Unit => Unit = null
def processDirectory(dir : File) : Unit @cps[Unit] = {
    val files = dir.listFiles
    var i = 0
    while (i < files.length) {
        val f = files(i)
        i += 1
        if (f.isDirectory)
            processDirectory(f)
        else {
            shift {
                k: (Unit => Unit) => {
                    cont = k // What is k here exactly?
                }
            }
            println(f)
        }
    }
}

reset {
    processDirectory(new File("/")) //
} 

Какое эквивалентное преобразование CPS для этого?

Моя догадка

// With i, files in a closure, the captured continuation can be
() => {
    println(f)
    while (i < files.length) {
        val f = files(i)
        i += 1
        if (f.isDirectory)
            processDirectory(f)
        else {
            shift {
                k: (Unit => Unit) => {
                    cont = k
                }
            }
            println(f)
        }
    }
}

И если в processDirectory открыт ресурс, куда я могу поместить закрытие ресурса код для этого?

...