在scalaz-stream中,如何在Sink终止时运行任务?

时间:2015-01-13 10:20:20

标签: scala scalaz-stream

我复制了一个来自http4s的例子:

// Print received Text frames, and, on completion, notify the console
  val sink: Sink[Task, WebSocketFrame] = Process.constant {
    case Text(t) => Task.delay(println(t))
    case f       => Task.delay(println(s"Unknown type: $f"))
  }.onComplete(Process.eval[Task, Nothing](Task{println("Terminated!")}).drain)

这会产生编译错误:“Unit类型的表达式不符合预期类型_A”

我只想打印“终止!”当接收器终止时

1 个答案:

答案 0 :(得分:1)

如果您从Process.eval调用中删除类型,它应该有效:

... .onComplete(Process.eval(Task{println("Terminated!")}).drain)

这里的问题是,您的Process.eval调用通过给出明确的类型来构建Process[Task, Unit]而不是Process[Task, Nothing]。之后调用drain会将Process[Task, Unit]转换为Process[Task, Nothing]

更新:以下是在完成时执行某些副作用的接收器示例:

scala> val sink = io.stdOutLines.onComplete(Process.eval_(Task(println("END"))))
sink: scalaz.stream.Process[[x]scalaz.concurrent.Task[x],String => scalaz.concurrent.Task[Unit]] = Append(Emit(Vector(<function1>)),Vector(<function1>, <function1>))

scala> Process("a", "b", "c").toSource.to(sink).run.run
a
b
c
END