https://github.com/amarpotghan/scala-fold
Composable folds
https://github.com/amarpotghan/scala-fold
composable fold scala
Last synced: about 2 months ago
JSON representation
Composable folds
- Host: GitHub
- URL: https://github.com/amarpotghan/scala-fold
- Owner: amarpotghan
- License: apache-2.0
- Created: 2016-07-07T14:18:59.000Z (over 9 years ago)
- Default Branch: master
- Last Pushed: 2018-07-18T14:55:40.000Z (over 7 years ago)
- Last Synced: 2023-07-02T11:39:56.878Z (over 2 years ago)
- Topics: composable, fold, scala
- Language: Scala
- Homepage:
- Size: 60.5 KB
- Stars: 13
- Watchers: 1
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
[](https://travis-ci.org/amarpotghan/scala-fold)
# scala-fold
Composable folds in Scala
# Introduction
This library defines the `Foldl` data type (a left fold) which can be combined in the applicative style such that resulting
fold requires only one traversal over the given structure.
Library comes with common folds. You can always define your own fold by providing a step function and initial value.
Library also comes with an extension method on scala's standard collections `foldWith`. You can use that on standard scala collections as follows,
```scala
import fold._
import Fold._
List(1, 2, 3).foldWith(sum[Int])
```
# Examples
## Simple sum of integers
```scala
scala> import fold._
import fold._
scala> import Fold._
import Fold._
scala> Seq(1, 2, 3).foldWith(sum[Int])
res1: Int = 6
```
## `Foldl`s are Applicatives, so we can compose `Foldl`s using applicative style:
```scala
scala> import fold._
import fold._
scala> import Fold._
import Fold._
scala> import scalaz._
import scalaz._
scala> type Fold[A] = Foldl[Double, A]
defined type alias Fold
scala> def mean = Apply[Fold].apply2(sum[Double], length[Double, Double])(_ / _)
mean: Fold[Double]
scala> Seq(1.0, 2.0, 3.0).foldWith(mean)
res1: Double = 2.0
```
Note that combined mean fold traverses List only once!
## Using Applicative syntax of Scalaz
```scala
scala> import fold._
scala> import Fold._
scala> import scalaz.syntax.apply._
import scalaz.syntax.apply._
scala> def mean = (sum[Double] |@| length[Double, Double]) (_ / _)
mean: fold.Foldl[Double,Double]
scala> Seq(1.0, 2.0, 3.0).foldWith(mean)
res3: Double = 2.0
```
## You can also conveniently use numeric operations on `Foldl`:
```scala
scala> import fold._
import fold._
scala> import Fold._
import Fold._
scala> def mean = sum[Double] / length[Double, Double]
mean: fold.Foldl[Double,Double]
scala> Seq(1.0, 2.0, 3.0).foldWith(mean)
res2: Double = 2.0
```
`(/)` function uses Foldl's applicative instance, so again List is traversed only once.
# Credits
* [Gabriel Gonzalez](https://github.com/Gabriel439)'s [foldl library](https://hackage.haskell.org/package/foldl)
* Phil Freeman's [purescript-folds](https://github.com/paf31/purescript-folds)
* Max Rabkin’s [Beautiful folding](http://squing.blogspot.sg/2008/11/beautiful-folding.html)
* Conal Elliott's [blogpost](http://conal.net/blog/posts/another-lovely-example-of-type-class-morphisms)
Feedbacks welcome!
# LICENSE
Distributed under the [Apache 2.0](LICENSE).
Copyright © 2016-2018 Amar Potghan.