Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More fixes for the fix god #957

Merged
merged 2 commits into from Jul 28, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 7 additions & 7 deletions modules/core/arrow-free/src/main/kotlin/arrow/free/Free.kt
Expand Up @@ -2,10 +2,10 @@ package arrow.free

import arrow.Kind
import arrow.core.Either
import arrow.core.FunctionK
import arrow.core.identity
import arrow.higherkind
import arrow.typeclasses.Applicative
import arrow.core.FunctionK
import arrow.typeclasses.Monad

inline fun <M, S, A> FreeOf<S, A>.foldMapK(f: FunctionK<S, M>, MM: Monad<M>): Kind<M, A> =
Expand Down Expand Up @@ -79,20 +79,20 @@ tailrec fun <S, A> Free<S, A>.step(): Free<S, A> =
}

@Suppress("UNCHECKED_CAST")
fun <M, S, A> Free<S, A>.foldMap(f: FunctionK<S, M>, MM: Monad<M>): Kind<M, A> = MM.run {
tailRecM(this@foldMap) {
fun <M, S, A> Free<S, A>.foldMap(f: FunctionK<S, M>, MM: Monad<M>): Kind<M, A> =
MM.tailRecM(this@foldMap) {
val x = it.step()
when (x) {
is Free.Pure<S, A> -> just(Either.Right(x.a))
is Free.Suspend<S, A> -> f(x.a).map({ Either.Right(it) })
is Free.Pure<S, A> -> MM.just(Either.Right(x.a))
is Free.Suspend<S, A> -> MM.run { f(x.a).map { Either.Right(it) } }
is Free.FlatMapped<S, A, *> -> {
val g = (x.fm as (A) -> Free<S, A>)
val c = x.c as Free<S, A>
c.foldMap(f, MM).map({ cc -> Either.Left(g(cc)) })
val folded = c.foldMap(f, MM)
MM.run { folded.map { cc -> Either.Left(g(cc)) } }
}
}
}
}

fun <S, A> A.free(): Free<S, A> = Free.just<S, A>(this)

Expand Down
Expand Up @@ -14,16 +14,16 @@ interface OptionTraverseFilterInstance : TraverseFilter<ForOption> {
override fun <A> Kind<ForOption, A>.filter(f: (A) -> Boolean): Option<A> =
fix().filter(f)

override fun <G, A, B> Kind<ForOption, A>.traverseFilter(AP: Applicative<G>, f: (A) -> Kind<G, Option<B>>): arrow.Kind<G, Option<B>> =
override fun <G, A, B> Kind<ForOption, A>.traverseFilter(AP: Applicative<G>, f: (A) -> Kind<G, Option<B>>): Kind<G, Option<B>> =
optionTraverseFilter(AP, f)

override fun <A, B> Kind<ForOption, A>.map(f: (A) -> B): Option<B> =
fix().map(f)

override fun <G, A, B> Kind<ForOption, A>.traverse(AP: Applicative<G>, f: (A) -> Kind<G, B>): arrow.Kind<G, Option<B>> =
override fun <G, A, B> Kind<ForOption, A>.traverse(AP: Applicative<G>, f: (A) -> Kind<G, B>): Kind<G, Option<B>> =
optionTraverse(AP, f)

override fun <A> Kind<ForOption, A>.exists(p: (A) -> Boolean): kotlin.Boolean =
override fun <A> Kind<ForOption, A>.exists(p: (A) -> Boolean): Boolean =
fix().exists(p)

override fun <A, B> Kind<ForOption, A>.foldLeft(b: B, f: (B, A) -> B): B =
Expand All @@ -32,13 +32,13 @@ interface OptionTraverseFilterInstance : TraverseFilter<ForOption> {
override fun <A, B> Kind<ForOption, A>.foldRight(lb: Eval<B>, f: (A, Eval<B>) -> Eval<B>): Eval<B> =
fix().foldRight(lb, f)

override fun <A> OptionOf<A>.forAll(p: (A) -> Boolean): kotlin.Boolean =
override fun <A> OptionOf<A>.forAll(p: (A) -> Boolean): Boolean =
fix().forall(p)

override fun <A> Kind<ForOption, A>.isEmpty(): kotlin.Boolean =
override fun <A> Kind<ForOption, A>.isEmpty(): Boolean =
fix().isEmpty()

override fun <A> Kind<ForOption, A>.nonEmpty(): kotlin.Boolean =
override fun <A> Kind<ForOption, A>.nonEmpty(): Boolean =
fix().nonEmpty()
}

Expand Down Expand Up @@ -71,7 +71,7 @@ object OptionMtlContext : OptionMonadFilterInstance, OptionTraverseFilterInstanc
fix().filter(f)

override fun <A, B> Kind<ForOption, A>.mapFilter(f: (A) -> Option<B>): Option<B> =
this.flatMap({ a -> f(a).fold({ empty<B>() }, { just(it) }) })
flatMap { a -> f(a).fold({ empty<B>() }, { just(it) }) }

override fun <A, B> Kind<ForOption, A>.map(f: (A) -> B): Option<B> =
fix().map(f)
Expand Down
Expand Up @@ -39,9 +39,9 @@ interface OptionTTraverseFilterInstance<F> :
fix().traverseFilter(f, AP, FFF())
}

fun <F, G, A, B> OptionT<F, A>.traverseFilter(f: (A) -> Kind<G, Option<B>>, GA: Applicative<G>, FF: Traverse<F>): Kind<G, OptionT<F, B>> = GA.run {
fun <F, G, A, B> OptionT<F, A>.traverseFilter(f: (A) -> Kind<G, Option<B>>, GA: Applicative<G>, FF: Traverse<F>): Kind<G, OptionT<F, B>> {
val fa = ComposedTraverseFilter(FF, Option.traverseFilter(), Option.applicative()).traverseFilterC(value, f, GA)
fa.map({ OptionT(FF.run { it.unnest().map({ it.fix() }) }) })
return GA.run { fa.map { OptionT(FF.run { it.unnest().map { it.fix() } }) } }
}

class OptionTMtlContext<F>(val MF: Monad<F>, val TF: TraverseFilter<F>) : OptionTMonadInstance<F>, OptionTMonoidKInstance<F>, OptionTTraverseFilterInstance<F> {
Expand Down
Expand Up @@ -6,7 +6,7 @@ import kotlin.coroutines.experimental.Continuation
import kotlin.coroutines.experimental.CoroutineContext
import kotlin.coroutines.experimental.startCoroutine

object CoroutineContextScheduler {
object CoroutineContextReactorScheduler {
private interface NonCancellableContinuation : Continuation<Unit>, Disposable

private val emptyDisposable = object : Disposable {
Expand Down
Expand Up @@ -6,7 +6,7 @@ import arrow.core.Eval
import arrow.core.Left
import arrow.core.Right
import arrow.core.identity
import arrow.effects.CoroutineContextScheduler.asScheduler
import arrow.effects.CoroutineContextReactorScheduler.asScheduler
import arrow.effects.typeclasses.Proc
import arrow.higherkind
import arrow.typeclasses.Applicative
Expand Down
Expand Up @@ -3,7 +3,7 @@ package arrow.effects
import arrow.core.Either
import arrow.core.Either.Left
import arrow.core.Either.Right
import arrow.effects.CoroutineContextScheduler.asScheduler
import arrow.effects.CoroutineContextReactorScheduler.asScheduler
import arrow.effects.typeclasses.Proc
import arrow.higherkind
import reactor.core.publisher.Mono
Expand Down
Expand Up @@ -8,7 +8,7 @@ import kotlin.coroutines.experimental.Continuation
import kotlin.coroutines.experimental.CoroutineContext
import kotlin.coroutines.experimental.startCoroutine

object CoroutineContextScheduler {
object CoroutineContextRx2Scheduler {
private interface NonCancellableContinuation : Continuation<Unit>, Disposable

fun CoroutineContext.asScheduler(): Scheduler =
Expand Down
Expand Up @@ -2,7 +2,7 @@ package arrow.effects

import arrow.Kind
import arrow.core.*
import arrow.effects.CoroutineContextScheduler.asScheduler
import arrow.effects.CoroutineContextRx2Scheduler.asScheduler
import arrow.effects.typeclasses.Proc
import arrow.higherkind
import arrow.typeclasses.Applicative
Expand Down Expand Up @@ -44,11 +44,10 @@ data class FlowableK<A>(val flowable: Flowable<A>) : FlowableKOf<A>, FlowableKKi
return Eval.defer { loop(this) }
}

fun <G, B> traverse(GA: Applicative<G>, f: (A) -> Kind<G, B>): Kind<G, FlowableK<B>> = GA.run {
foldRight(Eval.always { just(Flowable.empty<B>().k()) }) { a, eval ->
f(a).map2Eval(eval) { Flowable.concat(Flowable.just<B>(it.a), it.b.flowable).k() }
fun <G, B> traverse(GA: Applicative<G>, f: (A) -> Kind<G, B>): Kind<G, FlowableK<B>> =
foldRight(Eval.always { GA.just(Flowable.empty<B>().k()) }) { a, eval ->
GA.run { f(a).map2Eval(eval) { Flowable.concat(Flowable.just<B>(it.a), it.b.flowable).k() } }
}.value()
}

fun handleErrorWith(function: (Throwable) -> FlowableK<A>): FlowableK<A> =
flowable.onErrorResumeNext { t: Throwable -> function(t).flowable }.k()
Expand Down
@@ -1,7 +1,7 @@
package arrow.effects

import arrow.core.*
import arrow.effects.CoroutineContextScheduler.asScheduler
import arrow.effects.CoroutineContextRx2Scheduler.asScheduler
import arrow.effects.typeclasses.Proc
import arrow.higherkind
import io.reactivex.Maybe
Expand Down
Expand Up @@ -2,13 +2,13 @@ package arrow.effects

import arrow.Kind
import arrow.core.*
import arrow.effects.CoroutineContextRx2Scheduler.asScheduler
import arrow.effects.typeclasses.Proc
import arrow.higherkind
import arrow.typeclasses.Applicative
import io.reactivex.Observable
import io.reactivex.ObservableEmitter
import kotlin.coroutines.experimental.CoroutineContext
import arrow.effects.CoroutineContextScheduler.asScheduler

fun <A> Observable<A>.k(): ObservableK<A> = ObservableK(this)

Expand Down Expand Up @@ -43,11 +43,10 @@ data class ObservableK<A>(val observable: Observable<A>) : ObservableKOf<A>, Obs
return Eval.defer { loop(this) }
}

fun <G, B> traverse(GA: Applicative<G>, f: (A) -> Kind<G, B>): Kind<G, ObservableK<B>> = GA.run {
fun <G, B> traverse(GA: Applicative<G>, f: (A) -> Kind<G, B>): Kind<G, ObservableK<B>> =
foldRight(Eval.always { GA.just(Observable.empty<B>().k()) }) { a, eval ->
f(a).map2Eval(eval) { Observable.concat(Observable.just<B>(it.a), it.b.observable).k() }
GA.run { f(a).map2Eval(eval) { Observable.concat(Observable.just<B>(it.a), it.b.observable).k() } }
}.value()
}

fun handleErrorWith(function: (Throwable) -> ObservableK<A>): ObservableK<A> =
this.fix().observable.onErrorResumeNext { t: Throwable -> function(t).observable }.k()
Expand Down
Expand Up @@ -3,7 +3,7 @@ package arrow.effects
import arrow.core.Either
import arrow.core.Left
import arrow.core.Right
import arrow.effects.CoroutineContextScheduler.asScheduler
import arrow.effects.CoroutineContextRx2Scheduler.asScheduler
import arrow.effects.typeclasses.Proc
import arrow.higherkind
import io.reactivex.Single
Expand Down