All Projects → higherkindness → Droste

higherkindness / Droste

Licence: other
recursion schemes for cats; to iterate is human, to recurse, divine

Programming Languages

scala
5932 projects

Projects that are alternatives of or similar to Droste

Swiftrex
Swift + Redux + (Combine|RxSwift|ReactiveSwift) -> SwiftRex
Stars: ✭ 267 (-11%)
Mutual labels:  functional-programming
Elmboy
A Nintendo™ Game Boy™ Emulator written in Elm.
Stars: ✭ 285 (-5%)
Mutual labels:  functional-programming
Lambda
🔮 Estudos obscuros de programação funcional
Stars: ✭ 297 (-1%)
Mutual labels:  functional-programming
Underscore.py
Python port of underscore.js
Stars: ✭ 277 (-7.67%)
Mutual labels:  functional-programming
Scala With Cats
Source code for Scala with Cats
Stars: ✭ 283 (-5.67%)
Mutual labels:  functional-programming
Javascript For Everyone
A step by step guide to learn JavaScript and programming
Stars: ✭ 285 (-5%)
Mutual labels:  functional-programming
Programming
Code a program in a language of your choice.
Stars: ✭ 269 (-10.33%)
Mutual labels:  functional-programming
Aecor
Pure functional event sourcing runtime
Stars: ✭ 299 (-0.33%)
Mutual labels:  functional-programming
Tofu
Functional programming toolbox
Stars: ✭ 281 (-6.33%)
Mutual labels:  functional-programming
Hareactive
Purely functional reactive programming library
Stars: ✭ 293 (-2.33%)
Mutual labels:  functional-programming
Write You A Haskell
Building a modern functional compiler from first principles. (http://dev.stephendiehl.com/fun/)
Stars: ✭ 3,064 (+921.33%)
Mutual labels:  functional-programming
Throwing Function
Checked Exceptions-enabled Java 8+ functional interfaces + adapters
Stars: ✭ 279 (-7%)
Mutual labels:  functional-programming
Mobile App
See your city's air pollution measured in daily cigarettes. iOS/Android.
Stars: ✭ 291 (-3%)
Mutual labels:  functional-programming
Golang Tutorials
Go Tutorials - Let's get our hands really dirty by writing a lot of Golang code
Stars: ✭ 277 (-7.67%)
Mutual labels:  functional-programming
Funcshell
Improve your shell by making it functional through Haskell! (An update to Awkward)
Stars: ✭ 297 (-1%)
Mutual labels:  functional-programming
Haskell Study Startup
Launch your own Haskell study group. Now.
Stars: ✭ 269 (-10.33%)
Mutual labels:  functional-programming
Eslint Plugin Functional
ESLint rules to disable mutation and promote fp in JavaScript and TypeScript.
Stars: ✭ 282 (-6%)
Mutual labels:  functional-programming
Virtual Audio Graph
🎶 Library for declaratively manipulating the Web Audio API
Stars: ✭ 299 (-0.33%)
Mutual labels:  functional-programming
Android Cleanarchitecture Kotlin
This is a movies sample app in Kotlin, which is part of a serie of blog posts I have written about architecting android application using different approaches.
Stars: ✭ 3,646 (+1115.33%)
Mutual labels:  functional-programming
Hamsters
A mini Scala utility library
Stars: ✭ 292 (-2.67%)
Mutual labels:  functional-programming

Droste

Join the chat at https://gitter.im/higherkindness/droste

Droste is a recursion library for Scala.

SBT installation

Select a tagged release version (x.y.z) and then add the following to your SBT build:

libraryDependencies += "io.higherkindness" %% "droste-core" % "x.y.z"

Usage

Droste makes it easy to assemble morphisms. For example, calculating Fibonacci values can be done with a histomorphism if we model natural numbers as a chain of Option. We can easily unfold with an anamorphism and then fold to our result with a histomorphism.

import higherkindness.droste._
import higherkindness.droste.data._
import cats.implicits._

val natCoalgebra: Coalgebra[Option, BigDecimal] =
  Coalgebra(n => if (n > 0) Some(n - 1) else None)

val fibAlgebra: CVAlgebra[Option, BigDecimal] = CVAlgebra {
  case Some(r1 :< Some(r2 :< _)) => r1 + r2
  case Some(_ :< None)           => 1
  case None                      => 0
}

val fib: BigDecimal => BigDecimal = scheme.ghylo(
  fibAlgebra.gather(Gather.histo),
  natCoalgebra.scatter(Scatter.ana))
scala> fib(0)
res0: BigDecimal = 0

scala> fib(1)
res1: BigDecimal = 1

scala> fib(2)
res2: BigDecimal = 1

scala> fib(10)
res3: BigDecimal = 55

scala> fib(100)
res4: BigDecimal = 354224848179261915075

An anamorphism followed by a histomorphism is also known as a dynamorphism. Recursion scheme animals like dyna are available in the zoo:

val fibAlt: BigDecimal => BigDecimal =
  scheme.zoo.dyna(fibAlgebra, natCoalgebra)
scala> fibAlt(0)
res5: BigDecimal = 0

scala> fibAlt(1)
res6: BigDecimal = 1

scala> fibAlt(2)
res7: BigDecimal = 1

scala> fibAlt(10)
res8: BigDecimal = 55

scala> fibAlt(100)
res9: BigDecimal = 354224848179261915075

What if we want to do two things at once? Let's calculate a Fibonacci value and the sum of all squares.

val fromNatAlgebra: Algebra[Option, BigDecimal] = Algebra {
  case Some(n) => n + 1
  case None    => 0
}

// note: n is the fromNatAlgebra helper value from the previous level of recursion
val sumSquaresAlgebra: RAlgebra[BigDecimal, Option, BigDecimal] = RAlgebra {
  case Some((n, value)) => value + (n + 1) * (n + 1)
  case None             => 0
}

val sumSquares: BigDecimal => BigDecimal = scheme.ghylo(
  sumSquaresAlgebra.gather(Gather.zygo(fromNatAlgebra)),
  natCoalgebra.scatter(Scatter.ana))
scala> sumSquares(0)
res11: BigDecimal = 0

scala> sumSquares(1)
res12: BigDecimal = 1

scala> sumSquares(2)
res13: BigDecimal = 5

scala> sumSquares(10)
res14: BigDecimal = 385

scala> sumSquares(100)
res15: BigDecimal = 338350

Now we can zip the two algebras into one so that we calculate both results in one pass.

val fused: BigDecimal => (BigDecimal, BigDecimal) =
  scheme.ghylo(
    fibAlgebra.gather(Gather.histo) zip
    sumSquaresAlgebra.gather(Gather.zygo(fromNatAlgebra)),
    natCoalgebra.scatter(Scatter.ana))
scala> fused(0)
res16: (BigDecimal, BigDecimal) = (0,0)

scala> fused(1)
res17: (BigDecimal, BigDecimal) = (1,1)

scala> fused(2)
res18: (BigDecimal, BigDecimal) = (1,5)

scala> fused(10)
res19: (BigDecimal, BigDecimal) = (55,385)

scala> fused(100)
res20: (BigDecimal, BigDecimal) = (354224848179261915075,338350)

Droste includes athema, a math expression parser/processor, as a more extensive example of recursion schemes.

Credits

A substantial amount of Droste's code is a derivation-- or an alternative encoding-- of patterns pioneered by others. Droste has benefited from the excellent work in many other recursion libraries, blog posts, academic papers, etc. Notably, Droste has benefited from:

Thank you to everyone involved. Additionally, thanks to Greg Pfeil (@sellout) for answering my random questions over the last few years while I've been slowly learning (and using recursion) schemes.

Copyright and License

Copyright the maintainers, 2018-present.

All code is available to you under the Apache License, Version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0.

Logos provided by the very excellent @impurepics.

Disclamer

Please be advised that I have no idea what I am doing. Nevertheless, this project is already being used for real work with real data in real life.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].