使用 Scala 延续实现非阻塞 API
我正在尝试使用 Scala (2.9.0) 延续来构建看似阻塞的 API,但实际上是异步的。假设您想编写如下内容:
if(ask("Continue?")) //Prompts Yes/No
name = input("Enter your name")
如果用户按“是”,则 ask
返回一个布尔值,并且 input
要求输入一个值。想象一下这是从 Web 服务器调用的,其中 ask
和 input
不会阻止任何线程,它们只是在 Map 中存储延续(或会话,并不重要) much),然后显示带有提示的页面(释放大部分资源)。当响应返回时,它会在 Map 中查找延续并恢复代码。
到目前为止的问题是,我似乎无法找到一种合适的方法来定义 ask
和 input
来使用延续,而不将调用上下文的返回类型作为参数传递。
我得到的最接近的是做类似的事情:
#!/bin/sh
exec scala -P:continuations:enable -deprecation "$0" "$@"
!#
import util.continuations._
//Api code
def display[T](prompt: String) = shift {
cont: (Unit => T) => {
println(prompt)
cont()
}
}
//Client code
def foo() : Int = reset {
display[Int]("foo!") // <-- how do I get rid of the type annotation?
5
}
def bar() : Unit = reset {
display[Unit]("bar!")
}
println(foo())
bar()
我真的很想摆脱调用 display
时的类型注释。有谁知道实现这一目标的方法?我不在乎 API 定义是否变得更丑,只要客户端代码变得更简单即可。 谢谢!
I'm trying to use Scala (2.9.0) continuations to build a seemingly blocking API, but that actually is asynchronous. Suppose that you would like to write something like:
if(ask("Continue?")) //Prompts Yes/No
name = input("Enter your name")
Where ask
returns a boolean if the user pressed yes, and input
asks for a value. Picture this being called from a web server, where ask
and input
do not block any threads, they just store a continuation in a Map (or the session, doesn't matter much) before displaying the page with the prompt (releasing most resources). And when a response get's back, it looks-up the continuation in the Map and resumes the code.
The problem so far is that I cannot seem to be able to find a suitable way to define ask
and input
to use continuations without passing the calling context's return type as a parameter.
The closest I got is doing something like:
#!/bin/sh
exec scala -P:continuations:enable -deprecation "$0" "$@"
!#
import util.continuations._
//Api code
def display[T](prompt: String) = shift {
cont: (Unit => T) => {
println(prompt)
cont()
}
}
//Client code
def foo() : Int = reset {
display[Int]("foo!") // <-- how do I get rid of the type annotation?
5
}
def bar() : Unit = reset {
display[Unit]("bar!")
}
println(foo())
bar()
I really would like to get rid of the type annotation on calls to display
. Does anyone know of a way of achieving this? I don't care if the API definition gets uglier, as long as the client code gets simpler.
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我终于想通了:
诀窍是接受返回
Any
的方法(Homeresque:D'oh!)并返回Nothing
。如果你想实现一些返回值的东西,比如
ask
,你可以这样做:在上面的代码中,ask 返回一个
Boolean
。I finally figured it out:
The trick is accepting methods that return
Any
(Homeresque: D'oh!) and returningNothing
.If you want to implement something that returns a value, such as
ask
, you can do:In the above code, ask returns a
Boolean
.