fs2 Basics

This chapter covers the smart constructors, how to create streams and run them. fs2 is written in a functional style. The basic approach to creating a stream is to create a basic Stream object, then through combinators and other methods, compose a complete Process that you run when you choose to run it. The process may create values directly or, as is typically the case, it produces side effects, such as writing to a file.

fs2 uses functional programming techniques to give you streaming semantics and vocabularies. So while fs2 uses the "pipe" as a basic building block of composing your stream, underneath, a pipe is a function that transforms an input to an output within a F context. You could in fact write: mypipe(mystream1) to get the effect of the pipe on the input stream since a Pipe is literally a function but the streaming vocabulary suggests using mystream1.through(mypipe).

In reality within fs2, higher kinded functions (functions that take functions) is one of the key basic building block abstraction. Instead of the function application syntax, it is suggested that you use the "stream" syntax. In fact, most of the methods on defined in the Stream class are written as pipes e.g. mystream.map(...) is really pipe.map(mystream)(...).

Similarly, the basic building block for merging two streams, deterministically or not, is through a "pipe" concept that takes two Streams as inputs and outputs a Stream that combines the two input items together.

Just as important as higher kinded types, fs2 uses lazy evaluation to compose streams. Once composed, they are run with an "interpreter." The Free monad as well as Spark promote this style.

Higher kinded types and lazy evaluation are key functional concepts.

Last updated