Skip to content

Commit 0580ec7

Browse files
authored
Merge pull request #237 from kategory/paco-recursionschemes
Recursion schemes
2 parents 9c81e7a + 16001dd commit 0580ec7

File tree

14 files changed

+123
-87
lines changed

14 files changed

+123
-87
lines changed

kategory-core/src/main/kotlin/kategory/data/EitherT.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,8 @@ package kategory
8787
fun <C> foldR(lb: Eval<C>, f: (B, Eval<C>) -> Eval<C>, FF: Foldable<F>): Eval<C> = FF.compose(Either.foldable<A>()).foldRC(value, lb, f)
8888

8989
fun <G, C> traverse(f: (B) -> HK<G, C>, GA: Applicative<G>, FF: Traverse<F>): HK<G, EitherT<F, A, C>> {
90-
val fa = ComposedTraverse(FF, Either.traverse<A>(), Either.monad<A>()).traverseC(value, f, GA)
91-
return GA.map(fa, { EitherT(FF.map(it.lower(), { it.ev() })) })
90+
val fa: HK<G, HK<Nested<F, EitherKindPartial<A>>, C>> = ComposedTraverse(FF, Either.traverse<A>(), Either.monad<A>()).traverseC(value, f, GA)
91+
return GA.map(fa, { EitherT(FF.map(it.unnest(), { it.ev() })) })
9292
}
9393

9494
fun combineK(y: EitherTKind<F, A, B>, MF: Monad<F>): EitherT<F, A, B> =

kategory-core/src/main/kotlin/kategory/data/OptionT.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ package kategory
107107

108108
fun <G, B> traverse(f: (A) -> HK<G, B>, GA: Applicative<G>, FF: Traverse<F>): HK<G, OptionT<F, B>> {
109109
val fa = ComposedTraverse(FF, Option.traverse(), Option.applicative()).traverseC(value, f, GA)
110-
return GA.map(fa, { OptionT(FF.map(it.lower(), { it.ev() })) })
110+
return GA.map(fa, { OptionT(FF.map(it.unnest(), { it.ev() })) })
111111
}
112112

113113
fun <R> toLeft(default: () -> R, FF: Functor<F>): EitherT<F, A, R> =

kategory-core/src/main/kotlin/kategory/typeclasses/Composed.kt

+60-56
Original file line numberDiff line numberDiff line change
@@ -3,36 +3,40 @@ package kategory
33
/**
44
* https://www.youtube.com/watch?v=wvSP5qYiz4Y
55
*/
6-
interface ComposedType<out F, out G>
6+
interface Nested<out F, out G>
7+
8+
typealias NestedType<F, G, A> = HK<Nested<F, G>, A>
9+
10+
typealias UnnestedType<F, G, A> = HK<F, HK<G, A>>
711

812
@Suppress("UNCHECKED_CAST")
9-
fun <F, G, A> HK<F, HK<G, A>>.lift(): HK<ComposedType<F, G>, A> = this as HK<ComposedType<F, G>, A>
13+
fun <F, G, A> UnnestedType<F, G, A>.nest(): NestedType<F, G, A> = this as HK<Nested<F, G>, A>
1014

1115
@Suppress("UNCHECKED_CAST")
12-
fun <F, G, A, B> HK2<F, HK2<G, A, B>, HK2<G, A, B>>.liftB(): HK2<ComposedType<F, G>, A, B> = this as HK2<ComposedType<F, G>, A, B>
16+
fun <F, G, A> NestedType<F, G, A>.unnest(): HK<F, HK<G, A>> = this as HK<F, HK<G, A>>
1317

1418
@Suppress("UNCHECKED_CAST")
15-
fun <F, G, A> HK<ComposedType<F, G>, A>.lower(): HK<F, HK<G, A>> = this as HK<F, HK<G, A>>
19+
fun <F, G, A, B> HK2<F, HK2<G, A, B>, HK2<G, A, B>>.binest(): HK2<Nested<F, G>, A, B> = this as HK2<Nested<F, G>, A, B>
1620

1721
@Suppress("UNCHECKED_CAST")
18-
fun <F, G, A, B> HK2<ComposedType<F, G>, A, B>.lowerB(): HK2<F, HK2<G, A, B>, HK2<G, A, B>> = this as HK2<F, HK2<G, A, B>, HK2<G, A, B>>
22+
fun <F, G, A, B> HK2<Nested<F, G>, A, B>.biunnest(): HK2<F, HK2<G, A, B>, HK2<G, A, B>> = this as HK2<F, HK2<G, A, B>, HK2<G, A, B>>
1923

2024
interface ComposedFoldable<F, G> :
21-
Foldable<ComposedType<F, G>> {
25+
Foldable<Nested<F, G>> {
2226

2327
fun FF(): Foldable<F>
2428

2529
fun GF(): Foldable<G>
2630

27-
override fun <A, B> foldL(fa: HK<ComposedType<F, G>, A>, b: B, f: (B, A) -> B): B =
28-
FF().foldL(fa.lower(), b, { bb, aa -> GF().foldL(aa, bb, f) })
31+
override fun <A, B> foldL(fa: HK<Nested<F, G>, A>, b: B, f: (B, A) -> B): B =
32+
FF().foldL(fa.unnest(), b, { bb, aa -> GF().foldL(aa, bb, f) })
2933

30-
fun <A, B> foldLC(fa: HK<F, HK<G, A>>, b: B, f: (B, A) -> B): B = foldL(fa.lift(), b, f)
34+
fun <A, B> foldLC(fa: HK<F, HK<G, A>>, b: B, f: (B, A) -> B): B = foldL(fa.nest(), b, f)
3135

32-
override fun <A, B> foldR(fa: HK<ComposedType<F, G>, A>, lb: Eval<B>, f: (A, Eval<B>) -> Eval<B>): Eval<B> =
33-
FF().foldR(fa.lower(), lb, { laa, lbb -> GF().foldR(laa, lbb, f) })
36+
override fun <A, B> foldR(fa: HK<Nested<F, G>, A>, lb: Eval<B>, f: (A, Eval<B>) -> Eval<B>): Eval<B> =
37+
FF().foldR(fa.unnest(), lb, { laa, lbb -> GF().foldR(laa, lbb, f) })
3438

35-
fun <A, B> foldRC(fa: HK<F, HK<G, A>>, lb: Eval<B>, f: (A, Eval<B>) -> Eval<B>): Eval<B> = foldR(fa.lift(), lb, f)
39+
fun <A, B> foldRC(fa: HK<F, HK<G, A>>, lb: Eval<B>, f: (A, Eval<B>) -> Eval<B>): Eval<B> = foldR(fa.nest(), lb, f)
3640

3741
companion object {
3842
operator fun <F, G> invoke(FF: Foldable<F>, GF: Foldable<G>): ComposedFoldable<F, G> =
@@ -52,7 +56,7 @@ inline fun <F, reified G> Foldable<F>.compose(GT: Foldable<G> = foldable<G>()):
5256
}
5357

5458
interface ComposedTraverse<F, G> :
55-
Traverse<ComposedType<F, G>>,
59+
Traverse<Nested<F, G>>,
5660
ComposedFoldable<F, G> {
5761

5862
fun FT(): Traverse<F>
@@ -65,10 +69,10 @@ interface ComposedTraverse<F, G> :
6569

6670
override fun GF(): Foldable<G> = GT()
6771

68-
override fun <H, A, B> traverse(fa: HK<ComposedType<F, G>, A>, f: (A) -> HK<H, B>, HA: Applicative<H>): HK<H, HK<ComposedType<F, G>, B>> =
69-
HA.map(FT().traverse(fa.lower(), { ga -> GT().traverse(ga, f, HA) }, HA), { it.lift() })
72+
override fun <H, A, B> traverse(fa: HK<Nested<F, G>, A>, f: (A) -> HK<H, B>, HA: Applicative<H>): HK<H, HK<Nested<F, G>, B>> =
73+
HA.map(FT().traverse(fa.unnest(), { ga -> GT().traverse(ga, f, HA) }, HA), { it.nest() })
7074

71-
fun <H, A, B> traverseC(fa: HK<F, HK<G, A>>, f: (A) -> HK<H, B>, HA: Applicative<H>): HK<H, HK<ComposedType<F, G>, B>> = traverse(fa.lift(), f, HA)
75+
fun <H, A, B> traverseC(fa: HK<F, HK<G, A>>, f: (A) -> HK<H, B>, HA: Applicative<H>): HK<H, HK<Nested<F, G>, B>> = traverse(fa.nest(), f, HA)
7276

7377
companion object {
7478
operator fun <F, G> invoke(
@@ -85,7 +89,7 @@ interface ComposedTraverse<F, G> :
8589
}
8690
}
8791

88-
inline fun <reified F, reified G> Traverse<F>.compose(GT: Traverse<G> = traverse<G>(), GA: Applicative<G> = applicative<G>()): Traverse<ComposedType<F, G>> =
92+
inline fun <reified F, reified G> Traverse<F>.compose(GT: Traverse<G> = traverse<G>(), GA: Applicative<G> = applicative<G>()): Traverse<Nested<F, G>> =
8993
object :
9094
ComposedTraverse<F, G> {
9195
override fun FT(): Traverse<F> = this@compose
@@ -95,57 +99,57 @@ inline fun <reified F, reified G> Traverse<F>.compose(GT: Traverse<G> = traverse
9599
override fun GA(): Applicative<G> = GA
96100
}
97101

98-
interface ComposedSemigroupK<F, G> : SemigroupK<ComposedType<F, G>> {
102+
interface ComposedSemigroupK<F, G> : SemigroupK<Nested<F, G>> {
99103

100104
fun F(): SemigroupK<F>
101105

102-
override fun <A> combineK(x: HK<ComposedType<F, G>, A>, y: HK<ComposedType<F, G>, A>): HK<ComposedType<F, G>, A> = F().combineK(x.lower(), y.lower()).lift()
106+
override fun <A> combineK(x: HK<Nested<F, G>, A>, y: HK<Nested<F, G>, A>): HK<Nested<F, G>, A> = F().combineK(x.unnest(), y.unnest()).nest()
103107

104-
fun <A> combineKC(x: HK<F, HK<G, A>>, y: HK<F, HK<G, A>>): HK<ComposedType<F, G>, A> = combineK(x.lift(), y.lift())
108+
fun <A> combineKC(x: HK<F, HK<G, A>>, y: HK<F, HK<G, A>>): HK<Nested<F, G>, A> = combineK(x.nest(), y.nest())
105109

106110
companion object {
107-
operator fun <F, G> invoke(SF: SemigroupK<F>): SemigroupK<ComposedType<F, G>> =
111+
operator fun <F, G> invoke(SF: SemigroupK<F>): SemigroupK<Nested<F, G>> =
108112
object : ComposedSemigroupK<F, G> {
109113
override fun F(): SemigroupK<F> = SF
110114
}
111115
}
112116
}
113117

114-
inline fun <F, G> SemigroupK<F>.compose(): SemigroupK<ComposedType<F, G>> = object : ComposedSemigroupK<F, G> {
118+
inline fun <F, G> SemigroupK<F>.compose(): SemigroupK<Nested<F, G>> = object : ComposedSemigroupK<F, G> {
115119
override fun F(): SemigroupK<F> = this@compose
116120
}
117121

118-
interface ComposedMonoidK<F, G> : MonoidK<ComposedType<F, G>>, ComposedSemigroupK<F, G> {
122+
interface ComposedMonoidK<F, G> : MonoidK<Nested<F, G>>, ComposedSemigroupK<F, G> {
119123

120124
override fun F(): MonoidK<F>
121125

122-
override fun <A> empty(): HK<ComposedType<F, G>, A> = F().empty<HK<G, A>>().lift()
126+
override fun <A> empty(): HK<Nested<F, G>, A> = F().empty<HK<G, A>>().nest()
123127

124-
fun <A> emptyC(): HK<F, HK<G, A>> = empty<A>().lower()
128+
fun <A> emptyC(): HK<F, HK<G, A>> = empty<A>().unnest()
125129

126130
companion object {
127-
operator fun <F, G> invoke(MK: MonoidK<F>): MonoidK<ComposedType<F, G>> =
131+
operator fun <F, G> invoke(MK: MonoidK<F>): MonoidK<Nested<F, G>> =
128132
object : ComposedMonoidK<F, G> {
129133
override fun F(): MonoidK<F> = MK
130134
}
131135
}
132136
}
133137

134-
fun <F, G> MonoidK<F>.compose(): MonoidK<ComposedType<F, G>> = object : ComposedMonoidK<F, G> {
138+
fun <F, G> MonoidK<F>.compose(): MonoidK<Nested<F, G>> = object : ComposedMonoidK<F, G> {
135139
override fun F(): MonoidK<F> = this@compose
136140
}
137141

138-
interface ComposedFunctor<F, G> : Functor<ComposedType<F, G>> {
142+
interface ComposedFunctor<F, G> : Functor<Nested<F, G>> {
139143
fun F(): Functor<F>
140144

141145
fun G(): Functor<G>
142146

143-
override fun <A, B> map(fa: HK<ComposedType<F, G>, A>, f: (A) -> B): HK<ComposedType<F, G>, B> = F().map(fa.lower(), { G().map(it, f) }).lift()
147+
override fun <A, B> map(fa: HK<Nested<F, G>, A>, f: (A) -> B): HK<Nested<F, G>, B> = F().map(fa.unnest(), { G().map(it, f) }).nest()
144148

145-
fun <A, B> mapC(fa: HK<F, HK<G, A>>, f: (A) -> B): HK<F, HK<G, B>> = map(fa.lift(), f).lower()
149+
fun <A, B> mapC(fa: HK<F, HK<G, A>>, f: (A) -> B): HK<F, HK<G, B>> = map(fa.nest(), f).unnest()
146150

147151
companion object {
148-
operator fun <F, G> invoke(FF: Functor<F>, GF: Functor<G>): Functor<ComposedType<F, G>> =
152+
operator fun <F, G> invoke(FF: Functor<F>, GF: Functor<G>): Functor<Nested<F, G>> =
149153
object : ComposedFunctor<F, G> {
150154
override fun F(): Functor<F> = FF
151155

@@ -154,25 +158,25 @@ interface ComposedFunctor<F, G> : Functor<ComposedType<F, G>> {
154158
}
155159
}
156160

157-
inline fun <reified F, reified G> Functor<F>.compose(GF: Functor<G>): Functor<ComposedType<F, G>> = ComposedFunctor(this, GF)
161+
inline fun <reified F, reified G> Functor<F>.compose(GF: Functor<G>): Functor<Nested<F, G>> = ComposedFunctor(this, GF)
158162

159-
interface ComposedApplicative<F, G> : Applicative<ComposedType<F, G>>, ComposedFunctor<F, G> {
163+
interface ComposedApplicative<F, G> : Applicative<Nested<F, G>>, ComposedFunctor<F, G> {
160164
override fun F(): Applicative<F>
161165

162166
override fun G(): Applicative<G>
163167

164-
override fun <A, B> map(fa: HK<ComposedType<F, G>, A>, f: (A) -> B): HK<ComposedType<F, G>, B> = ap(fa, pure(f))
168+
override fun <A, B> map(fa: HK<Nested<F, G>, A>, f: (A) -> B): HK<Nested<F, G>, B> = ap(fa, pure(f))
165169

166-
override fun <A> pure(a: A): HK<ComposedType<F, G>, A> = F().pure(G().pure(a)).lift()
170+
override fun <A> pure(a: A): HK<Nested<F, G>, A> = F().pure(G().pure(a)).nest()
167171

168-
override fun <A, B> ap(fa: HK<ComposedType<F, G>, A>, ff: HK<ComposedType<F, G>, (A) -> B>):
169-
HK<ComposedType<F, G>, B> = F().ap(fa.lower(), F().map(ff.lower(), { gfa: HK<G, (A) -> B> -> { ga: HK<G, A> -> G().ap(ga, gfa) } })).lift()
172+
override fun <A, B> ap(fa: HK<Nested<F, G>, A>, ff: HK<Nested<F, G>, (A) -> B>):
173+
HK<Nested<F, G>, B> = F().ap(fa.unnest(), F().map(ff.unnest(), { gfa: HK<G, (A) -> B> -> { ga: HK<G, A> -> G().ap(ga, gfa) } })).nest()
170174

171-
fun <A, B> apC(fa: HK<F, HK<G, A>>, ff: HK<F, HK<G, (A) -> B>>): HK<F, HK<G, B>> = ap(fa.lift(), ff.lift()).lower()
175+
fun <A, B> apC(fa: HK<F, HK<G, A>>, ff: HK<F, HK<G, (A) -> B>>): HK<F, HK<G, B>> = ap(fa.nest(), ff.nest()).unnest()
172176

173177
companion object {
174178
operator fun <F, G> invoke(FF: Applicative<F>, GF: Applicative<G>)
175-
: Applicative<ComposedType<F, G>> =
179+
: Applicative<Nested<F, G>> =
176180
object : ComposedApplicative<F, G> {
177181
override fun F(): Applicative<F> = FF
178182

@@ -181,14 +185,14 @@ interface ComposedApplicative<F, G> : Applicative<ComposedType<F, G>>, ComposedF
181185
}
182186
}
183187

184-
inline fun <reified F, reified G> Applicative<F>.compose(GA: Applicative<G> = applicative<G>()): Applicative<ComposedType<F, G>> = ComposedApplicative(this, GA)
188+
inline fun <reified F, reified G> Applicative<F>.compose(GA: Applicative<G> = applicative<G>()): Applicative<Nested<F, G>> = ComposedApplicative(this, GA)
185189

186-
interface ComposedAlternative<F, G> : Alternative<ComposedType<F, G>>, ComposedApplicative<F, G>, ComposedMonoidK<F, G> {
190+
interface ComposedAlternative<F, G> : Alternative<Nested<F, G>>, ComposedApplicative<F, G>, ComposedMonoidK<F, G> {
187191
override fun F(): Alternative<F>
188192

189193
companion object {
190194
operator fun <F, G> invoke(AF: Alternative<F>, AG: Applicative<G>)
191-
: Alternative<ComposedType<F, G>> =
195+
: Alternative<Nested<F, G>> =
192196
object : ComposedAlternative<F, G> {
193197
override fun F(): Alternative<F> = AF
194198

@@ -197,19 +201,19 @@ interface ComposedAlternative<F, G> : Alternative<ComposedType<F, G>>, ComposedA
197201
}
198202
}
199203

200-
inline fun <reified F, reified G> Alternative<F>.compose(GA: Applicative<G> = applicative<G>()): Alternative<ComposedType<F, G>> = ComposedAlternative(this, GA)
204+
inline fun <reified F, reified G> Alternative<F>.compose(GA: Applicative<G> = applicative<G>()): Alternative<Nested<F, G>> = ComposedAlternative(this, GA)
201205

202-
interface ComposedFunctorFilter<F, G> : FunctorFilter<ComposedType<F, G>>, ComposedFunctor<F, G> {
206+
interface ComposedFunctorFilter<F, G> : FunctorFilter<Nested<F, G>>, ComposedFunctor<F, G> {
203207

204208
override fun F(): Functor<F>
205209

206210
override fun G(): FunctorFilter<G>
207211

208-
override fun <A, B> mapFilter(fga: HK<ComposedType<F, G>, A>, f: (A) -> Option<B>): HK<ComposedType<F, G>, B> =
209-
F().map(fga.lower(), { G().mapFilter(it, f) }).lift()
212+
override fun <A, B> mapFilter(fga: HK<Nested<F, G>, A>, f: (A) -> Option<B>): HK<Nested<F, G>, B> =
213+
F().map(fga.unnest(), { G().mapFilter(it, f) }).nest()
210214

211215
fun <A, B> mapFilterC(fga: HK<F, HK<G, A>>, f: (A) -> Option<B>): HK<F, HK<G, B>> =
212-
mapFilter(fga.lift(), f).lower()
216+
mapFilter(fga.nest(), f).unnest()
213217

214218
companion object {
215219
operator fun <F, G> invoke(FF: Functor<F>, FFG: FunctorFilter<G>): ComposedFunctorFilter<F, G> =
@@ -222,28 +226,28 @@ interface ComposedFunctorFilter<F, G> : FunctorFilter<ComposedType<F, G>>, Compo
222226
}
223227

224228
inline fun <reified F, reified G> Functor<F>.composeFilter(FFG: FunctorFilter<G> = functorFilter()):
225-
FunctorFilter<ComposedType<F, G>> = ComposedFunctorFilter(this, FFG)
229+
FunctorFilter<Nested<F, G>> = ComposedFunctorFilter(this, FFG)
226230

227-
interface ComposedBifoldable<F, G> : Bifoldable<ComposedType<F, G>> {
231+
interface ComposedBifoldable<F, G> : Bifoldable<Nested<F, G>> {
228232
fun F(): Bifoldable<F>
229233

230234
fun G(): Bifoldable<G>
231235

232-
override fun <A, B, C> bifoldLeft(fab: HK2<ComposedType<F, G>, A, B>, c: C, f: (C, A) -> C, g: (C, B) -> C): C =
233-
F().bifoldLeft(fab.lowerB(), c,
236+
override fun <A, B, C> bifoldLeft(fab: HK2<Nested<F, G>, A, B>, c: C, f: (C, A) -> C, g: (C, B) -> C): C =
237+
F().bifoldLeft(fab.biunnest(), c,
234238
{ cc: C, gab: HK2<G, A, B> -> G().bifoldLeft(gab, cc, f, g) },
235239
{ cc: C, gab: HK2<G, A, B> -> G().bifoldLeft(gab, cc, f, g) })
236240

237-
override fun <A, B, C> bifoldRight(fab: HK2<ComposedType<F, G>, A, B>, c: Eval<C>, f: (A, Eval<C>) -> Eval<C>, g: (B, Eval<C>) -> Eval<C>): Eval<C> =
238-
F().bifoldRight(fab.lowerB(), c,
241+
override fun <A, B, C> bifoldRight(fab: HK2<Nested<F, G>, A, B>, c: Eval<C>, f: (A, Eval<C>) -> Eval<C>, g: (B, Eval<C>) -> Eval<C>): Eval<C> =
242+
F().bifoldRight(fab.biunnest(), c,
239243
{ gab: HK2<G, A, B>, cc: Eval<C> -> G().bifoldRight(gab, cc, f, g) },
240244
{ gab: HK2<G, A, B>, cc: Eval<C> -> G().bifoldRight(gab, cc, f, g) })
241245

242246
fun <A, B, C> bifoldLeftC(fab: HK2<F, HK2<G, A, B>, HK2<G, A, B>>, c: C, f: (C, A) -> C, g: (C, B) -> C): C =
243-
bifoldLeft(fab.liftB(), c, f, g)
247+
bifoldLeft(fab.binest(), c, f, g)
244248

245249
fun <A, B, C> bifoldRightC(fab: HK2<F, HK2<G, A, B>, HK2<G, A, B>>, c: Eval<C>, f: (A, Eval<C>) -> Eval<C>, g: (B, Eval<C>) -> Eval<C>): Eval<C> =
246-
bifoldRight(fab.liftB(), c, f, g)
250+
bifoldRight(fab.binest(), c, f, g)
247251

248252
companion object {
249253
operator fun <F, G> invoke(BF: Bifoldable<F>, BG: Bifoldable<G>): ComposedBifoldable<F, G> =
@@ -255,4 +259,4 @@ interface ComposedBifoldable<F, G> : Bifoldable<ComposedType<F, G>> {
255259
}
256260
}
257261

258-
inline fun <reified F, reified G> Bifoldable<F>.compose(BG: Bifoldable<G> = bifoldable()): Bifoldable<ComposedType<F, G>> = ComposedBifoldable(this, BG)
262+
inline fun <reified F, reified G> Bifoldable<F>.compose(BG: Bifoldable<G> = bifoldable()): Bifoldable<Nested<F, G>> = ComposedBifoldable(this, BG)

kategory-core/src/test/kotlin/kategory/data/BifoldableTests.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,6 @@ class BifoldableTests : UnitSpec() {
2323

2424
val eitherComposeEither = eitherBifoldable.compose(eitherBifoldable)
2525

26-
testLaws(BifoldableLaws.laws(eitherComposeEither, { cf: Int -> Either.Right(Either.Right(cf)).liftB() }, Eq.any()))
26+
testLaws(BifoldableLaws.laws(eitherComposeEither, { cf: Int -> Either.Right(Either.Right(cf)).binest() }, Eq.any()))
2727
}
2828
}

kategory-core/src/test/kotlin/kategory/instances/ComposedInstancesTest.kt

+10-10
Original file line numberDiff line numberDiff line change
@@ -8,30 +8,30 @@ typealias OptionTNel = HK<OptionTKindPartial<NonEmptyListHK>, Int>
88

99
@RunWith(KTestJUnitRunner::class)
1010
class ComposedInstancesTest : UnitSpec() {
11-
val EQ_OPTION_NEL: Eq<HK<ComposedType<OptionHK, NonEmptyListHK>, Int>> = Eq { a, b ->
12-
a.lower().ev() == b.lower().ev()
11+
val EQ_OPTION_NEL: Eq<NestedType<OptionHK, NonEmptyListHK, Int>> = Eq { a, b ->
12+
a.unnest().ev() == b.unnest().ev()
1313
}
1414

15-
val EQ_LKW_OPTION: Eq<HK<ComposedType<ListKWHK, OptionHK>, Int>> = Eq { a, b ->
16-
a.lower().ev() == b.lower().ev()
15+
val EQ_LKW_OPTION: Eq<NestedType<ListKWHK, OptionHK, Int>> = Eq { a, b ->
16+
a.unnest().ev() == b.unnest().ev()
1717
}
1818

19-
val EQ_OPTIONT_ID_NEL: Eq<HK<ComposedType<OptionTKindPartial<IdHK>, OptionTKindPartial<NonEmptyListHK>>, Int>> =
19+
val EQ_OPTIONT_ID_NEL: Eq<NestedType<OptionTKindPartial<IdHK>, OptionTKindPartial<NonEmptyListHK>, Int>> =
2020
Eq { a, b ->
21-
a.lower().value().value().fold(
22-
{ b.lower().value().value().isEmpty },
21+
a.unnest().value().value().fold(
22+
{ b.unnest().value().value().isEmpty },
2323
{ optionA: OptionTNel ->
24-
b.lower().value().value().ev().fold(
24+
b.unnest().value().value().ev().fold(
2525
{ false },
2626
{ it.value() == optionA.value() })
2727
})
2828
}
2929

30-
val cf: (Int) -> HK<ComposedType<OptionHK, NonEmptyListHK>, Int> = { it.nel().some().lift() }
30+
val cf: (Int) -> HK<Nested<OptionHK, NonEmptyListHK>, Int> = { it.nel().some().nest() }
3131

3232
init {
3333
testLaws(FunctorLaws.laws(ComposedFunctor(Option.functor(), NonEmptyList.functor()), cf, EQ_OPTION_NEL))
34-
testLaws(FunctorFilterLaws.laws(ComposedFunctorFilter(OptionT.functorFilter(Id.monad()), OptionT.functorFilter(NonEmptyList.monad())), { OptionT.pure(OptionT.pure(it, NonEmptyList.monad()), Id.monad()).lift() }, EQ_OPTIONT_ID_NEL))
34+
testLaws(FunctorFilterLaws.laws(ComposedFunctorFilter(OptionT.functorFilter(Id.monad()), OptionT.functorFilter(NonEmptyList.monad())), { OptionT.pure(OptionT.pure(it, NonEmptyList.monad()), Id.monad()).nest() }, EQ_OPTIONT_ID_NEL))
3535
testLaws(ApplicativeLaws.laws(ComposedApplicative(Option.applicative(), NonEmptyList.applicative()), EQ_OPTION_NEL))
3636
testLaws(FoldableLaws.laws(ComposedFoldable(Option.foldable(), NonEmptyList.foldable()), cf, Eq.any()))
3737
testLaws(TraverseLaws.laws(ComposedTraverse(Option.traverse(), NonEmptyList.traverse(), NonEmptyList.applicative()), ComposedFunctor.invoke(Option.functor(), NonEmptyList.functor()), cf, EQ_OPTION_NEL))

kategory-recursion/README.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Recursion schemes for Kategory
2+
3+
This package is complex and highly experimental.
4+
5+
Do not use.

kategory-recursion/build.gradle

+2-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ dependencies {
1111
testCompile project(':kategory-test')
1212
}
1313

14-
apply from: rootProject.file('gradle/gradle-mvn-push.gradle')
14+
// FIXME(paco): re-enable when it's prod-ready
15+
//apply from: rootProject.file('gradle/gradle-mvn-push.gradle')
1516
apply from: 'generated-kotlin-sources.gradle'
1617
apply plugin: 'kotlin-kapt'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package kategory
2+
3+
@higherkind data class EnvT<out B, out W, out A>(val ask: B, val lower: HK<W, A>) : EnvTKind<B, W, A>

0 commit comments

Comments
 (0)