Recipe: Debugging with toString

If you need to print out the data in your process, the easiest way is to dump the content out to stdout. This tip came from the youtube video: Intro to FS2 - Part3: Concurrency.

The key idea is that to dump data for inspection, you can define a pipe that passes the data through untouched, but as a side effect, prints the data using a println statement. Since println is IO, its an effect we need to manage in a F[_].

fs2> def log[A](prefix: String): Pipe[Task, A,A] = _.evalMap{ a => Task.delay{ println(s"$prefix> $a"); a}} 
defined function log

then just pass the content through the pipe.

log works by mapping into the input stream and evaluating (through eval) the effect inside, which is a Task that prints out the debug message. The syntax _.evalMap is just a way to declare a function. The _ says take whatever is given as input and map into it. Because we specifically added the type information to log, the scala compiler knew it needed a function definition (a Pipe is just a function Stream[F[_], I] => Stream[F[_], O] and combined with _, it found one.

In the example below, we use run because we are not interested in the output:

fs2> Stream.range(1,10).through(log("logger")).run.unsafeRun 
logger> 1
logger> 2
logger> 3
logger> 4
logger> 5
logger> 6
logger> 7
logger> 8
logger> 9

Last updated