想不出一个 callcc 实际应用的例子 , 搞了个示例性的 . 目的是 :
1. 示范怎样扑捉 continuation
2. 示范怎样调用 continuation
3. 示范 callcc 的效果
4. 这是个 Delimited Continuation 的例子
package com.bellcard.continuations
object ContTrial {
case class M[+A](in: (A=> Any )=> Any ) {
def apply(f:A=> Any ) = in(f)
def map[B](f: A => B):M[B] = bind( this , {x: A => unit(f(x))} )
def flatMap[B](f: A => M[B]):M[B] = bind( this , f)
}
def bind[A,B](m:M[A], f:A=>M[B]):M[B] =
M(k => m.in (x => f(x).in(k)))
def unit[A](x:A):M[A] = M( {k:(A=> Any ) => k(x)} )
def callcc[A](e:(A=>M[A])=>M[A]):M[A] =
M(k => e(a => M(ignored => k(a))).in(k))
def main(args : Array [String]) : Unit = {
var okcc: Int =>M[ Int ] = null
var errcc: Int =>M[ Int ] = null
var speccc: Int =>M[ Int ] = null
val cc = callcc[ Int ](ok=>
callcc[ Int ](specific=>
callcc[ Int ](err=>{
okcc = ok
errcc= err
speccc= specific
println( "in callcc" )
unit[ Int ](1)
}) flatMap {x=>{println( "err cc" );unit(x)}}
) flatMap { x=>{println( "specific cc" ); unit(x)}}
) flatMap{x=>{println( "ok cc" );unit(x)}}
cc(println)
println( "ooooookkkkkkkccccccccc" )
okcc(10)(println)
println( "sssspppppeecciifffiiiicccccc" )
speccc(40)(println)
println( "eeeeerrrrrrccccccccc" )
errcc(30)(println)
}
}
输出 :
in callcc
err cc
specific cc
ok cc
1
ooooookkkkkkkccccccccc
ok cc
10
sssspppppeecciifffiiiicccccc
specific cc
ok cc
40
eeeeerrrrrrccccccccc
err cc
specific cc
ok cc
30
在最内层的 callcc 中 , 用 okcc = ok, errcc=err, speccc=specific 来扑捉 continuation.
内 层 callcc 包含 外 层 callcc 的 continuation(是不是叫inside-out?). 例如 , 调用 errcc(30) 会调用 okcc 和 speccc. 而调用 okcc 则不会调用 errcc 和 speccc, 因为它是最外层的
Continuation 是有边界的 (delimited), 在最外层的 callcc 是其边界