You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

39 lines
1.4 KiB

package nova.monadic_sfx.util.reactive
import cats.implicits._
import monix.reactive.Observable
import monix.reactive.ObservableLike
object Reducer {
/**
* Creates a Reducer which yields a new State, as-well as an Observable of Effects
* Effects are Actions which will be executed after the Action that caused them to occur.
* This is accomplished by subscribing to the Effects Observable within the stores scan loop.
*
* CAUTION: There is currently a bug which causes the Effect-States to emit,
* before the State of the action that caused the effects is emitted.
* However, this only effects immediate emissions of the Effects Observable, delayed emissions should be fine.
* @param f The Reducing Function returning the (Model, Effects) tuple.
*/
def withEffects[F[_]: ObservableLike, A, M](
f: (M, A) => (M, F[A])
): Reducer[A, M] = (s: M, a: A) => f(s, a).map(ObservableLike[F].apply)
/**
* Creates a reducer which just transforms the state, without additional effects.
*/
def apply[A, M](f: (M, A) => M): Reducer[A, M] =
(s: M, a: A) => f(s, a) -> Observable.empty
/**
* Creates a Reducer with an optional effect.
*/
def withOptionalEffects[F[_]: ObservableLike, A, M](
f: (M, A) => (M, Option[F[A]])
): Reducer[A, M] =
(s: M, a: A) =>
f(s, a).map(
_.fold[Observable[A]](Observable.empty)(ObservableLike[F].apply)
)
}