1

I have copied an example from 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)

This yields a compilation error: "Expression of type Unit doesn't conform to expected type _A"

I just want to printline "Terminated!" when the sink gets terminated

Frank S. Thomas
  • 4,725
  • 2
  • 28
  • 47
Atle
  • 428
  • 3
  • 11

1 Answers1

1

It should work if you remove the types from the Process.eval call:

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

The problem here is that your Process.eval call constructs a Process[Task, Unit] and not a Process[Task, Nothing] as you ask for by giving the types explicity. Calling drain converts the Process[Task, Unit] to a Process[Task, Nothing] afterwards.

Update: Here is an example of a sink that performs some side effect on completion:

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
Frank S. Thomas
  • 4,725
  • 2
  • 28
  • 47
  • 1
    or you can even use `onComplete(eval_(/* your task */))`. Note using of `eval_` instead of `eval` – Pavel Chlupacek Jan 14 '15 at 08:20
  • Thank you for the reply, but that leaves me with ```Expression of type Process[Any,Nothin] doesn't conform to expected type stream.Sink[Task,WebsocketBits.WebSocketFrame]``` – Atle Jan 14 '15 at 13:09
  • @Atle try to break up your sink into two `val`s and maybe add type annotations to them. The process you pass to `onComplete` should be of type `Process[Task, Nothing]`. – Frank S. Thomas Jan 16 '15 at 15:08
  • i have refactored out the "completing" process into `val p :Process[Task,Nothing]`, the compiler still emits the same error – Atle Jan 19 '15 at 12:39
  • When i split out the _onComplete_ call like this `val p: Process[Task, Nothing] = Process.eval(Task {println("Terminated!")}).drain val sink: Sink[Task, WebSocketFrame] = Process.constant { case Text(t, x) => Task.delay(println(t)) case f => Task.delay(println(s"Unknown type: $f")) } val sinkWithComplete:Sink[Task, WebSocketFrame] = sink.onComplete(p)`it works – Atle Jan 19 '15 at 12:45