Streams


Streams

A lightweight F#/C# library for efficient functional-style pipelines on streams of data.

Install via NuGet:
PM> Install-Package Streams
PM> Install-Package Streams.CSharp

The main design behind Streams is inspired by Java 8 Streams and is based on the observation that many functional pipelines follow the pattern:

1: 
source/generator |> lazy |> lazy |> lazy |> eager/reduce
  • Source/generator are functions that create Streams like Stream.ofArray/Stream.init.
  • Lazy functions take in streams and return streams like Stream.map/Stream.filter, these operations are fused together for efficient iteration.
  • Eager/reduce are functions like Stream.iter/Stream.sum that force the Stream to evaluate up to that point.

The main difference between LINQ/Seq and Streams is that LINQ is about composing external iterators (Enumerable/Enumerator) and Streams is based on the continuation-passing-style composition of internal iterators.

Example pipeline

1: 
2: 
3: 
4: 
5: 
6: 
7: 
8: 
9: 
open Nessos.Streams

[|1L .. 10000000L|]
|> Stream.ofArray
|> Stream.filter (fun x -> x % 2L = 0L)
|> Stream.map (fun x -> x + 1L)
|> Stream.sortBy id
|> Stream.take 99
|> Stream.sum

Performance

The Streams library provides performance benefits compared to other LINQ-style combinator libraries. Please see the benchmarks in Performance.md for more information.

References

Contributing and copyright

The project is hosted on GitHub where you can report issues, fork the project and submit pull requests.

The library is available under the Apache License. For more information see the License file in the GitHub repository.

namespace Nessos
namespace Nessos.Streams
Multiple items
module Stream

from Nessos.Streams

--------------------
type Stream<'T> =
  private { Run: Context<'T> -> Iterable }
    member private RunBulk : ctxt:Context<'T> -> unit
    override ToString : unit -> string
val ofArray : source:'T [] -> Stream<'T>
val filter : predicate:('T -> bool) -> stream:Stream<'T> -> Stream<'T>
val x : int64
val map : f:('T -> 'R) -> stream:Stream<'T> -> Stream<'R>
val sortBy : projection:('T -> 'Key) -> stream:Stream<'T> -> Stream<'T> (requires comparison)
val id : x:'T -> 'T
val take : n:int -> stream:Stream<'T> -> Stream<'T>
val sum : stream:Stream<'T> -> 'T (requires member ( + ) and member get_Zero)
Fork me on GitHub