Origami
The origami project provides "Monadic folds" to process streams of data in a composable fashion. Monadic folds come in 2 flavors:
- pure folds: for computing things like min,max,average,hash,...
- effectul folds: for sinking data to a file for example
The general form of a Fold is
trait Fold[M[_], A, B] {
  type S
  def start: M[S]
  def fold: (S, A) => M[S]
  def end(s: S): M[B]
} 
where:
- Mmust have a- Monadinstance
- Ais the type of input elements, being fed one by one to the fold
- Bis the final result
- Sis the type of some internal state
- startis a method to "initialize" the fold
- endis a method to "finalize" the fold
- foldis the method called for each element- Aand current type- S
Folds can be composed to produce "larger" folds, doing several things at the same time. For example:
import org.atnos.origami._
import org.atnos.origami.fold._
import org.atnos.origami.folds._
import org.atnos.origami.syntax.foldable._
import cats.Eval
import cats.data.EitherT
import cats.implicits._
import java.io.PrintWriter
type Safe[A] = EitherT[Eval, Throwable, A]
def protect[A](a: =>A): Safe[A] = EitherT.right(Eval.later(a))
def saveToFile(path: String): Sink[Safe, Int] =
  bracket(
    // create a new writer
    protect(new PrintWriter(path)))(
    
    // write a new line in the file
    (w, i: Int) => protect { w.write(s"i=$i\n"); w })(
    
    // close the writer
    w => protect(w.close))
val stats: Fold[Safe, Int, ((Int, Int), Double)] =
  (minimumOr(0) <*> maximumOr(Int.MaxValue) <*> averageDouble).into[Safe] <*
    saveToFile("target/readme-example")
val elements = (1 to 10).toList
elements.foldWith(stats).value.value 
In the example above we create a stats fold composed from:
- 3 pure folds assembled with <*>(thezipoperator)
- 1 effectful fold saveToFileusing theSafemonad
The Safe monad is necessary here to use the bracket combinator which creates a Fold acquiring resources at the beginning of the run and eventually release them. It needs both the ability to deal with errors (with EitherT) and to delay computations (with Eval).
 JarCasting
 JarCasting

