tofu.data.calc.Translator.scala Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of tofu-kernel_3 Show documentation
Show all versions of tofu-kernel_3 Show documentation
Opinionated set of tools for functional programming in Scala
package tofu.data.calc
import tofu.higherKind.bi.FunBK
import scala.annotation.unchecked.{uncheckedVariance => uv}
import tofu.data.Nothing2T
trait Translator[-F[_, _], +G[+_, +_], ST, +RI, -RO] { self =>
def mapRead(ro: RO): RI
def trans[E, A](fa: F[E, A]): CalcM[G, RO, ST, ST, E, A]
def translateState[S, E, A](fa: F[E, A]): CalcM[G, RO, (ST, S), (ST, S), E, A] = trans(fa).focusFirst
def setR[R](r: R): Translator[F, G, ST, R, RO] = new Translator[F, G, ST, R, RO] {
override def mapRead(ro: RO): R = r
override def trans[E, A](fa: F[E, A]): CalcM[G, RO, ST, ST, E, A] = self.trans(fa)
override def setR[R1](r1: R1): Translator[F, G, ST, R1, RO] = self.setR(r1)
}
}
object Translator {
type Uno[F[_], E, A] = F[A]
def apply[F[_, _], R, S]: Applied[F, R, S] = new Applied
def uno[F[_], R, S]: Applied[Uno[F, _, _], R, S] = new Applied[Uno[F, _, _], R, S]
class Applied[F[_, _], R, ST] {
type E
type A
type S
def apply[G[+_, +_]](mk: AsStateK[F, G, ST, R, E, A]): Translator[F, G, ST, R, R] = mk
def pure(mk: AsStateK[F, Nothing2T, ST, R, E, A]): Translator[F, Nothing2T, ST, R, R] = mk
}
abstract class As[-F[_, _], G[+_, +_], ST, R] extends Translator[F, G, ST, R, R] {
def mapRead(ro: R): R = ro
}
abstract class AsStateK[-F[_, _], G[+_, +_], ST, R, E1, A1] extends As[F, G, ST, R] {
def translateArb(fa: F[E1, A1]): CalcM[G, R, ST, ST, E1, A1]
def trans[E, A](fa: F[E, A]): CalcM[G, R, ST, ST, E, A] =
translateArb(fa.asInstanceOf[F[E1, A1]]).asInstanceOf[CalcM[G, R, ST, ST, E, A]]
}
}
trait ITranslator[-F[_, _], +G[+_, +_], +RI, -RO] extends Translator[F, G, Any, RI, RO] { self =>
def mapRead(ro: RO): RI
def translate[S, E, A](fa: F[E, A]): CalcM[G, RO, S, S, E, A]
def trans[E, A](fa: F[E, A]): CalcM[G, RO, Any, Any, E, A] = translate[Any, E, A](fa)
override def setR[R](r: R): ITranslator[F, G, R, RO] = new ITranslator[F, G, R, RO] {
override def mapRead(ro: RO): R = r
override def translate[S, E, A](fa: F[E, A]): CalcM[G, RO, S, S, E, A] = self.translate(fa)
override def setR[R1](r1: R1): ITranslator[F, G, R1, RO] = self.setR(r1)
}
}
object ITranslator {
def apply[F[_, _], R]: Applied[F, R] = new Applied
def mapK[F[_, _], G[+_, +_], R](fk: F FunBK G): ITranslator[F, G, R, R] = new ITranslator[F, G, R, R] {
override def mapRead(ro: R): R = ro
override def translate[S, E, A](fa: F[E, A]): CalcM[G, R, S, S, E, A] = CalcM.lift(fk(fa))
}
def flatMapK[F[_, _], G[+_, +_], R](fk: F FunBK G): ITranslator[F, G, R, R] = new ITranslator[F, G, R, R] {
override def mapRead(ro: R): R = ro
override def translate[S, E, A](fa: F[E, A]): CalcM[G, R, S, S, E, A] = CalcM.lift(fk(fa))
}
class Applied[F[_, _], R] {
type E
type A
type S
def mapK[G[+_, +_]](mk: AsMapK[F, G, R, E, A]): ITranslator[F, G, R, R] = mk
def flatMapK[G[+_, +_]](mk: AsFlatMapK[F, G, R, S, E, A]): ITranslator[F, G, R, R] = mk
}
abstract class As[-F[_, _], G[+_, +_], R] extends ITranslator[F, G, R, R] {
def mapRead(ro: R): R = ro
}
abstract class AsMapK[-F[_, _], G[+_, +_], R, E1, A1] extends As[F, G, R] {
def translateArb(fa: F[E1, A1]): G[E1, A1]
def translate[S, E, A](fa: F[E, A]): CalcM[G, R, S, S, E, A] =
CalcM.lift(translateArb(fa.asInstanceOf[F[E1, A1]]).asInstanceOf[G[E, A]])
}
abstract class AsFlatMapK[-F[_, _], G[+_, +_], R, S1, E1, A1] extends As[F, G, R] {
def translateArb(fa: F[E1, A1]): CalcM[G, R, S1, S1, E1, A1]
def translate[S, E, A](fa: F[E, A]): CalcM[G, R, S, S, E, A] =
translateArb(fa.asInstanceOf[F[E1, A1]]).asInstanceOf[CalcM[G, R, S, S, E, A]]
}
}
class TranslatePack[+F[+_, +_], -R, -SI, +SO, +E, +A](private val calc: CalcM[F, R, SI, SO, E, A]) extends AnyVal {
type EArb
type AArb
type SArb
def mapK[G[+_, +_]](fk: FunBK.Maker[F, G, EArb, AArb]): CalcM[G, R, SI, SO, E, A] = calc.mapK(fk)
def flatMapK[G[+_, +_]](fk: ITranslator.AsFlatMapK[F, G, R @uv, SArb, EArb, AArb]): CalcM[G, R, SI, SO, E, A] =
calc.translate(fk)
def state[ST]: TranslateStatePack[F, R, SI, SO, E, A, ST] = new TranslateStatePack(calc)
}
class TranslateStatePack[+F[+_, +_], -R, -SI, +SO, +E, +A, ST](private val calc: CalcM[F, R, SI, SO, E, A])
extends AnyVal {
type EArb
type AArb
def keep[G[+_, +_]](
fk: Translator.AsStateK[F, G, ST, R @uv, EArb, AArb]
): CalcM[G, R, (ST, SI), (ST, SO), E, A] =
calc.translateState(fk)
def apply[G[+_, +_]](
fk: Translator.AsStateK[F, G, ST, R @uv, EArb, AArb]
)(implicit s: Unit <:< SI): CalcM[G, R, ST, ST, E, A] =
CalcM.get[ST].mapState(st => (st, (): SI)) *>> calc.translateState(fk).mapState(_._1)
def pure(
fk: Translator.AsStateK[F, Nothing2T, ST, R @uv, EArb, AArb]
)(implicit s: Unit <:< SI): CalcM[λ[(`+x`, `+y`) => Nothing], R, ST, ST, E, A] =
CalcM.get[ST].mapState(st => (st, (): SI)) *>> (calc.translateState(fk).mapState(_._1))
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy