Skip to content

Commit

Permalink
Fix parameter order
Browse files Browse the repository at this point in the history
  • Loading branch information
aedans committed Apr 16, 2018
1 parent c8cc68d commit 371b38b
Show file tree
Hide file tree
Showing 11 changed files with 33 additions and 34 deletions.
4 changes: 2 additions & 2 deletions src/main/kotlin/io/github/aedans/katalyst/Recursion.kt
Expand Up @@ -22,10 +22,10 @@ typealias Coalgebra<F, A> = (A) -> Kind<F, A>
* The composition of cata and ana.
*/
fun <F, A, B> hylo(
a: A,
FF: Functor<F>,
alg: Algebra<F, Eval<B>>,
coalg: Coalgebra<F, A>,
FF: Functor<F>
a: A
): B = FF.run {
fun h(a: A): Eval<B> = alg(coalg(a).map { Eval.defer { h(it) } })
return h(a).value()
Expand Down
4 changes: 2 additions & 2 deletions src/main/kotlin/io/github/aedans/katalyst/data/Fix.kt
Expand Up @@ -16,11 +16,11 @@ data class Fix<out A>(val unfix: Kind<A, Eval<FixOf<A>>>) : FixOf<A> {

@instance(Fix::class)
interface FixBirecursiveInstance : Birecursive<ForFix> {
override fun <F> projectT(t: FixOf<F>, FF: Functor<F>) = FF.run {
override fun <F> projectT(FF: Functor<F>, t: FixOf<F>) = FF.run {
t.fix().unfix.map { it.value() }
}

override fun <F> embedT(t: Kind<F, Eval<FixOf<F>>>, FF: Functor<F>) =
override fun <F> embedT(FF: Functor<F>, t: Kind<F, Eval<FixOf<F>>>) =
Eval.later { Fix(t) }
}

Expand Down
12 changes: 6 additions & 6 deletions src/main/kotlin/io/github/aedans/katalyst/data/Mu.kt
Expand Up @@ -19,24 +19,24 @@ abstract class Mu<out F> : MuOf<F> {

@instance(Mu::class)
interface MuBirecursiveInstance : Birecursive<ForMu> {
override fun <F> embedT(t: Kind<F, Eval<MuOf<F>>>, FF: Functor<F>): Eval<Mu<F>> = FF.run {
override fun <F> embedT(FF: Functor<F>, t: Kind<F, Eval<MuOf<F>>>): Eval<Mu<F>> = FF.run {
Eval.now(object : Mu<F>() {
override fun <A> unMu(fa: Algebra<F, Eval<A>>) =
fa(t.map { it.flatMap { it.fix().unMu(fa) } })
})
}

override fun <F> projectT(t: MuOf<F>, FF: Functor<F>): Kind<F, MuOf<F>> = FF.run {
t.cata({ ff ->
override fun <F> projectT(FF: Functor<F>, t: MuOf<F>): Kind<F, MuOf<F>> = FF.run {
t.cata(FF, { ff ->
Eval.later {
ff.map { f ->
embedT(f.value().map(::Now), FF).value()
embedT(FF, f.value().map(::Now)).value()
}
}
}, FF)
})
}

override fun <F, A> MuOf<F>.cata(alg: Algebra<F, Eval<A>>, FF: Functor<F>): A =
override fun <F, A> MuOf<F>.cata(FF: Functor<F>, alg: Algebra<F, Eval<A>>): A =
fix().unMu(alg).value()
}

Expand Down
8 changes: 4 additions & 4 deletions src/main/kotlin/io/github/aedans/katalyst/data/Nu.kt
Expand Up @@ -22,17 +22,17 @@ class Nu<out F>(val a: Any?, val unNu: Coalgebra<F, Any?>) : NuOf<F> {

@instance(Nu::class)
interface NuBirecursiveInstance : Birecursive<ForNu> {
override fun <F> projectT(t: NuOf<F>, FF: Functor<F>): Kind<F, Nu<F>> = FF.run {
override fun <F> projectT(FF: Functor<F>, t: NuOf<F>): Kind<F, Nu<F>> = FF.run {
val fix = t.fix()
val unNu = fix.unNu
unNu(fix.a).map { Nu(it, unNu) }
}

override fun <F> embedT(t: Kind<F, Eval<NuOf<F>>>, FF: Functor<F>) = FF.run {
Eval.now(Nu.invoke(t) { f -> f.map { nu -> projectT(nu.value(), FF).map(::Now) } })
override fun <F> embedT(FF: Functor<F>, t: Kind<F, Eval<NuOf<F>>>) = FF.run {
Eval.now(Nu.invoke(t) { f -> f.map { nu -> projectT(FF, nu.value()).map(::Now) } })
}

override fun <F, A> A.ana(coalg: Coalgebra<F, A>, FF: Functor<F>) =
override fun <F, A> A.ana(FF: Functor<F>, coalg: Coalgebra<F, A>) =
Nu(this, coalg)
}

Expand Down
4 changes: 2 additions & 2 deletions src/main/kotlin/io/github/aedans/katalyst/fixedpoint/List.kt
Expand Up @@ -42,9 +42,9 @@ fun <A> fromGListAlgebra() = Algebra<ListPattern<A>, Eval<List<A>>> {
}

inline fun <reified T, A> List<A>.toGList(CT: Corecursive<T>): GList<T, A> = CT.run {
ana(toGListCoalgebra(), ComposedFunctor(Option.functor(), Tuple2.functor<A>()))
ana(ComposedFunctor(Option.functor(), Tuple2.functor<A>()), toGListCoalgebra())
}

inline fun <reified T, A> GList<T, A>.toCofree(RT: Recursive<T>): List<A> = RT.run {
cata(fromGListAlgebra(), ComposedFunctor(Option.functor(), Tuple2.functor<A>()))
cata(ComposedFunctor(Option.functor(), Tuple2.functor<A>()), fromGListAlgebra())
}
4 changes: 2 additions & 2 deletions src/main/kotlin/io/github/aedans/katalyst/fixedpoint/Nat.kt
Expand Up @@ -27,9 +27,9 @@ fun fromGNatAlgebra() = Algebra<NatPattern, Eval<Int>> {
}

inline fun <reified T> Int.toGNat(CT: Corecursive<T>): GNat<T> = CT.run {
ana(toGNatCoalgebra(), Option.functor())
ana(Option.functor(), toGNatCoalgebra())
}

inline fun <reified T> GNat<T>.toInt(RT: Recursive<T>): Int = RT.run {
cata(fromGNatAlgebra(), Option.functor())
cata(Option.functor(), fromGNatAlgebra())
}
Expand Up @@ -4,7 +4,6 @@ import arrow.Kind
import arrow.core.*
import arrow.data.NonEmptyList
import arrow.data.nel
import arrow.syntax.collections.prependTo
import arrow.typeclasses.ComposedFunctor
import arrow.typeclasses.Nested
import arrow.typeclasses.nest
Expand Down Expand Up @@ -44,9 +43,9 @@ fun <A> fromGNonEmptyListAlgebra() = Algebra<NonEmptyListPattern<A>, Eval<NonEmp
}

inline fun <reified T, A> List<A>.toGNonEmptyList(CT: Corecursive<T>): GList<T, A> = CT.run {
ana(toGListCoalgebra(), ComposedFunctor(Option.functor(), Tuple2.functor<A>()))
ana(ComposedFunctor(Option.functor(), Tuple2.functor<A>()), toGListCoalgebra())
}

inline fun <reified T, A> GList<T, A>.toNonEmptyList(RT: Recursive<T>): List<A> = RT.run {
cata(fromGListAlgebra(), ComposedFunctor(Option.functor(), Tuple2.functor<A>()))
cata(ComposedFunctor(Option.functor(), Tuple2.functor<A>()), fromGListAlgebra())
}
Expand Up @@ -14,15 +14,15 @@ interface Corecursive<T> {
/**
* Implementation for embed.
*/
fun <F> embedT(t: Kind<F, Eval<Kind<T, F>>>, FF: Functor<F>): Eval<Kind<T, F>>
fun <F> embedT(FF: Functor<F>, t: Kind<F, Eval<Kind<T, F>>>): Eval<Kind<T, F>>

/**
* Creates a algebra given a functor.
*/
fun <F> embed(FF: Functor<F>): Algebra<F, Eval<Kind<T, F>>> = { embedT(it, FF) }
fun <F> embed(FF: Functor<F>): Algebra<F, Eval<Kind<T, F>>> = { embedT(FF, it) }

/**
* Unfold into any recursive type.
*/
fun <F, A> A.ana(coalg: Coalgebra<F, A>, FF: Functor<F>): Kind<T, F> = hylo(this, embed(FF), coalg, FF)
fun <F, A> A.ana(FF: Functor<F>, coalg: Coalgebra<F, A>): Kind<T, F> = hylo(FF, embed(FF), coalg, this)
}
Expand Up @@ -14,17 +14,17 @@ interface Recursive<T> {
/**
* Implementation for project.
*/
fun <F> projectT(t: Kind<T, F>, FF: Functor<F>): Kind<F, Kind<T, F>>
fun <F> projectT(FF: Functor<F>, t: Kind<T, F>): Kind<F, Kind<T, F>>

/**
* Creates a coalgebra given a functor.
*/
fun <F> project(FF: Functor<F>): Coalgebra<F, Kind<T, F>> =
{ projectT(it, FF) }
{ projectT(FF, it) }

/**
* Fold generalized over any recursive type.
*/
fun <F, A> Kind<T, F>.cata(alg: Algebra<F, Eval<A>>, FF: Functor<F>): A =
hylo(this, alg, project(FF), FF)
fun <F, A> Kind<T, F>.cata(FF: Functor<F>, alg: Algebra<F, Eval<A>>): A =
hylo(FF, alg, project(FF), this)
}
4 changes: 2 additions & 2 deletions src/test/kotlin/io/github/aedans/katalyst/examples/Expr.kt
Expand Up @@ -53,7 +53,7 @@ fun evalExprAlgebra() = Algebra<ForExprPattern, Eval<Int>> {
fun main(args: Array<String>) {
val expr = plus(plus(int(1), int(2)), neg(plus(int(3), int(4))))
Fix.recursive().run {
expr.cata(evalExprAlgebra(), ExprPattern.functor()) // -4
expr.cata(ExprPattern.functor(), evalExprAlgebra()) // -4
}
}

Expand All @@ -65,7 +65,7 @@ class ExprTest : UnitSpec() {

"expr.cata(alg = evalExprAlgebra()) should be -4" {
Fix.recursive().run {
expr.cata(evalExprAlgebra(), ExprPattern.functor())
expr.cata(ExprPattern.functor(), evalExprAlgebra())
} shouldEqual -4
}
}
Expand Down
Expand Up @@ -14,14 +14,14 @@ object BirecursiveLaws {
Law("Birecursive Laws: ana . cata == hylo") {
forAll(intGen) {
val composed = it
.ana(toGNatCoalgebra(), Option.functor())
.cata(fromGNatAlgebra(), Option.functor())
val hylo = hylo(it, fromGNatAlgebra(), toGNatCoalgebra(), Option.functor())
.ana(Option.functor(), toGNatCoalgebra())
.cata(Option.functor(), fromGNatAlgebra())
val hylo = hylo(Option.functor(), fromGNatAlgebra(), toGNatCoalgebra(), it)
hylo == composed
}
},
Law("Birecursive Laws: Stack-safe cata, ana, and hylo") {
100000.toGNat(BT).cata(fromGNatAlgebra(), Option.functor()) shouldEqual 100000
100000.toGNat(BT).cata(Option.functor(), fromGNatAlgebra()) shouldEqual 100000
}
)
}
Expand Down

0 comments on commit 371b38b

Please sign in to comment.