我正在使用Netty库(GitHub的第4版).它在Scala中运行良好,但我希望我的库能够使用延续传递样式进行异步等待.
传统上使用Netty你会做这样的事情(一个示例异步连接操作):
//client is a ClientBootstrap
val future:ChannelFuture = client.connect(remoteAddr);
future.addListener(new ChannelFutureListener {
def operationComplete (f:ChannelFuture) = {
//here goes the code that happens when the connection is made
}
})
Run Code Online (Sandbox Code Playgroud)
如果你正在实现一个库(我是),那么你基本上有三个简单的选项,允许库的用户在建立连接后做东西:
我想做的是第四种选择; 我没有在上面的计数中包含它,因为它并不简单.
我想使用scala分隔的continuation来使库有点像一个阻塞库,但它将在幕后无阻塞:
class MyLibraryClient {
def connect(remoteAddr:SocketAddress) = {
shift { retrn: (Unit => Unit) => {
val future:ChannelFuture = client.connect(remoteAddr);
future.addListener(new ChannelFutureListener {
def operationComplete(f:ChannelFuture) = {
retrn();
}
});
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
想象一下,其他读/写操作以相同的方式实现.这样做的目的是用户的代码看起来更像这样:
reset {
val conn = new …Run Code Online (Sandbox Code Playgroud) 我一直试图用scala continuation来解决复杂的输入问题.我一直在阅读我能找到的所有材料,包括延续包中的参考文档.我想我已经在某种程度上弄明白了,当你想到这一点时它会让你觉得有些意义.
我认为我对它的理解(以及我的一些问题)可以通过这个程序得到最好的总结:
package com.whatever;
import scala.util.continuations._;
object methods {
/* The method takes an Int as its parameter. Theoretically, at some point in the future,
* it will return a Float to the remainder of the continuation. This example does it
* immediately but doesn't have to (for example it could be calling a network service
* to do the transformation)
*
* Float @cpsParam[Unit,Float] means that whatever part of the reset{} that is captured
* as a closure …Run Code Online (Sandbox Code Playgroud) 我的一个项目使用scala功能混合,看起来不能很好地混合在一起:
我遇到的问题是类型类实例派生失败,如果:
Lazy这是我可以编写的用于重现问题的最小代码量:
import shapeless._
trait Show[A] {
def show(a: A): String
}
object Show {
def from[A](f: A => String): Show[A] = new Show[A] {
override def show(a: A) = f(a)
}
implicit val intShow: Show[Int] = Show.from(_.toString)
implicit def singletonShow[A](implicit
sa: Show[A]
): Show[A :: HNil] = Show.from {
case (a :: HNil) => sa.show(a)
}
implicit def singletonCaseClassShow[A, H <: HList](implicit
gen: Generic.Aux[A, H],
sh: Lazy[Show[H]]
): Show[A] = Show.from …Run Code Online (Sandbox Code Playgroud)