Skip to content

Instantly share code, notes, and snippets.

@GrafBlutwurst
Created August 24, 2023 11:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save GrafBlutwurst/b640837399bc44898700129274e741ec to your computer and use it in GitHub Desktop.
Save GrafBlutwurst/b640837399bc44898700129274e741ec to your computer and use it in GitHub Desktop.
package tech.rivero.core.util.monocle
import monocle.AppliedIso
import monocle.AppliedLens
import monocle.AppliedOptional
import monocle.AppliedPrism
import monocle.AppliedTraversal
import monocle.syntax._
object Syntax {
implicit class AppliedFoldSyntaxExtension[S, A](opt: AppliedFold[S, A]) {
def indexFocus[I, A1](i: I)(implicit evIndex: monocle.function.Index[A, I, A1]) = opt.index(i)
def lastFocus[A1](implicit ev: Last[A, A1]) = opt.andThen(ev.last)
def headFocus[A1](implicit ev: Head[A, A1]) = opt.andThen(ev.head)
def right[L, A1](implicit evA: A =:= Either[L, A1]): AppliedFold[S, A1] = {
val adapted: monocle.Fold[S, Either[L, A1]] = evA.substituteCo[monocle.Fold[S, *]](opt.optic)
val prism = monocle.std.either.pStdRight[L, A1, A1]
AppliedFold(opt.value, adapted.andThen(prism))
}
def left[R, A1](implicit evA: A =:= Either[A1, R]): AppliedFold[S, A1] = {
val adapted: monocle.Fold[S, Either[A1, R]] = evA.substituteCo[monocle.Fold[S, *]](opt.optic)
val prism = monocle.std.either.pStdLeft[A1, R, A1]
AppliedFold(opt.value, adapted.andThen(prism))
}
}
implicit class AppliedGetterSyntaxExtension[S, A](opt: AppliedGetter[S, A]) {
def right[L, A1](implicit evA: A =:= Either[L, A1]): AppliedFold[S, A1] = {
val adapted: monocle.Getter[S, Either[L, A1]] =
evA.substituteCo[monocle.Getter[S, *]](opt.optic)
val prism: monocle.Optional[Either[L, A1], A1] = monocle.std.either.pStdRight[L, A1, A1]
AppliedFold(opt.value, adapted.andThen(prism))
}
def left[R, A1](implicit evA: A =:= Either[A1, R]): AppliedFold[S, A1] = {
val adapted: monocle.Getter[S, Either[A1, R]] =
evA.substituteCo[monocle.Getter[S, *]](opt.optic)
val prism = monocle.std.either.pStdLeft[A1, R, A1]
AppliedFold(opt.value, adapted.andThen(prism))
}
}
implicit class AppliedOptionalSyntaxExtension[S, A](opt: AppliedOptional[S, A]) {
def indexFocus[I, A1](i: I)(implicit
evIndex: monocle.function.Index[A, I, A1]
): AppliedOptional[S, A1] = opt.index(i)
def lastFocus[A1](implicit ev: Last[A, A1]) = opt.andThen(ev.last)
def headFocus[A1](implicit ev: Head[A, A1]) = opt.andThen(ev.head)
}
implicit class AppliedPOptionalSyntaxExtension[S, T, A, B](opt: AppliedPOptional[S, T, A, B]) {
def right[L, A1, B1](implicit
evA: A =:= Either[L, A1],
evB: B =:= Either[L, B1],
): AppliedPOptional[S, T, A1, B1] = {
val adapted: monocle.POptional[S, T, Either[L, A1], Either[L, B1]] =
evB.substituteCo[monocle.POptional[S, T, Either[L, A1], *]](
evA.substituteCo[monocle.POptional[S, T, *, B]](opt.optic)
)
val prism = monocle.std.either.pStdRight[L, A1, B1]
AppliedPOptional(opt.value, adapted.andThen(prism))
}
def left[R, A1, B1](implicit
evA: A =:= Either[A1, R],
evB: B =:= Either[B1, R],
): AppliedPOptional[S, T, A1, B1] = {
val adapted: monocle.POptional[S, T, Either[A1, R], Either[B1, R]] =
evB.substituteCo[monocle.POptional[S, T, Either[A1, R], *]](
evA.substituteCo[monocle.POptional[S, T, *, B]](opt.optic)
)
val prism = monocle.std.either.pStdLeft[A1, R, B1]
AppliedPOptional(opt.value, adapted.andThen(prism))
}
}
implicit class AppliedIsoSyntaxExtension[S, A](opt: AppliedIso[S, A]) {
def indexFocus[I, A1](i: I)(implicit
evIndex: monocle.function.Index[A, I, A1]
): AppliedOptional[S, A1] = opt.index(i)
def lastFocus[A1](implicit ev: Last[A, A1]) = opt.andThen(ev.last)
def headFocus[A1](implicit ev: Head[A, A1]) = opt.andThen(ev.head)
}
implicit class AppliedPIsoSyntaxExtension[S, T, A, B](opt: AppliedPIso[S, T, A, B]) {
def right[L, A1, B1](implicit
evA: A =:= Either[L, A1],
evB: B =:= Either[L, B1],
): AppliedPPrism[S, T, A1, B1] = {
val adapted: monocle.PIso[S, T, Either[L, A1], Either[L, B1]] =
evB.substituteCo[monocle.PIso[S, T, Either[L, A1], *]](
evA.substituteCo[monocle.PIso[S, T, *, B]](opt.optic)
)
val prism = monocle.std.either.pStdRight[L, A1, B1]
AppliedPPrism(opt.value, adapted.andThen(prism))
}
def left[R, A1, B1](implicit
evA: A =:= Either[A1, R],
evB: B =:= Either[B1, R],
): AppliedPPrism[S, T, A1, B1] = {
val adapted: monocle.PIso[S, T, Either[A1, R], Either[B1, R]] =
evB.substituteCo[monocle.PIso[S, T, Either[A1, R], *]](
evA.substituteCo[monocle.PIso[S, T, *, B]](opt.optic)
)
val prism = monocle.std.either.pStdLeft[A1, R, B1]
AppliedPPrism(opt.value, adapted.andThen(prism))
}
}
implicit class AppliedLensSyntaxExtension[S, A](opt: AppliedLens[S, A]) {
def indexFocus[I, A1](i: I)(implicit
evIndex: monocle.function.Index[A, I, A1]
): AppliedOptional[S, A1] = opt.index(i)
def lastFocus[A1](implicit ev: Last[A, A1]) = opt.andThen(ev.last)
def headFocus[A1](implicit ev: Head[A, A1]) = opt.andThen(ev.head)
}
implicit class AppliedPLensSyntaxExtension[S, T, A, B](opt: AppliedPLens[S, T, A, B]) {
def right[L, A1, B1](implicit
evA: A =:= Either[L, A1],
evB: B =:= Either[L, B1],
): AppliedPOptional[S, T, A1, B1] = {
val adapted: monocle.PLens[S, T, Either[L, A1], Either[L, B1]] =
evB.substituteCo[monocle.PLens[S, T, Either[L, A1], *]](
evA.substituteCo[monocle.PLens[S, T, *, B]](opt.optic)
)
val prism = monocle.std.either.pStdRight[L, A1, B1]
AppliedPOptional(opt.value, adapted.andThen(prism))
}
def left[R, A1, B1](implicit
evA: A =:= Either[A1, R],
evB: B =:= Either[B1, R],
): AppliedPOptional[S, T, A1, B1] = {
val adapted: monocle.PLens[S, T, Either[A1, R], Either[B1, R]] =
evB.substituteCo[monocle.PLens[S, T, Either[A1, R], *]](
evA.substituteCo[monocle.PLens[S, T, *, B]](opt.optic)
)
val prism = monocle.std.either.pStdLeft[A1, R, B1]
AppliedPOptional(opt.value, adapted.andThen(prism))
}
}
implicit class AppliedPrismSyntaxExtension[S, A](opt: AppliedPrism[S, A]) {
def indexFocus[I, A1](i: I)(implicit
evIndex: monocle.function.Index[A, I, A1]
): AppliedOptional[S, A1] = opt.index(i)
def lastFocus[A1](implicit ev: Last[A, A1]) = opt.andThen(ev.last)
def headFocus[A1](implicit ev: Head[A, A1]) = opt.andThen(ev.head)
}
implicit class AppliedPPrismSyntaxExtension[S, T, A, B](opt: AppliedPPrism[S, T, A, B]) {
def right[L, A1, B1](implicit
evA: A =:= Either[L, A1],
evB: B =:= Either[L, B1],
): AppliedPPrism[S, T, A1, B1] = {
val adapted: monocle.PPrism[S, T, Either[L, A1], Either[L, B1]] =
evB.substituteCo[monocle.PPrism[S, T, Either[L, A1], *]](
evA.substituteCo[monocle.PPrism[S, T, *, B]](opt.optic)
)
val prism = monocle.std.either.pStdRight[L, A1, B1]
AppliedPPrism(opt.value, adapted.andThen(prism))
}
def left[R, A1, B1](implicit
evA: A =:= Either[A1, R],
evB: B =:= Either[B1, R],
): AppliedPPrism[S, T, A1, B1] = {
val adapted: monocle.PPrism[S, T, Either[A1, R], Either[B1, R]] =
evB.substituteCo[monocle.PPrism[S, T, Either[A1, R], *]](
evA.substituteCo[monocle.PPrism[S, T, *, B]](opt.optic)
)
val prism = monocle.std.either.pStdLeft[A1, R, B1]
AppliedPPrism(opt.value, adapted.andThen(prism))
}
}
implicit class AppliedPSetterSyntaxExtension[S, T, A, B](opt: AppliedPSetter[S, T, A, B]) {
def right[L, A1, B1](implicit
evA: A =:= Either[L, A1],
evB: B =:= Either[L, B1],
): AppliedPSetter[S, T, A1, B1] = {
val adapted: monocle.PSetter[S, T, Either[L, A1], Either[L, B1]] =
evB.substituteCo[monocle.PSetter[S, T, Either[L, A1], *]](
evA.substituteCo[monocle.PSetter[S, T, *, B]](opt.optic)
)
val prism = monocle.std.either.pStdRight[L, A1, B1]
AppliedPSetter(opt.value, adapted.andThen(prism))
}
def left[R, A1, B1](implicit
evA: A =:= Either[A1, R],
evB: B =:= Either[B1, R],
): AppliedPSetter[S, T, A1, B1] = {
val adapted: monocle.PSetter[S, T, Either[A1, R], Either[B1, R]] =
evB.substituteCo[monocle.PSetter[S, T, Either[A1, R], *]](
evA.substituteCo[monocle.PSetter[S, T, *, B]](opt.optic)
)
val prism = monocle.std.either.pStdLeft[A1, R, B1]
AppliedPSetter(opt.value, adapted.andThen(prism))
}
}
implicit class AppliedTraversalSyntaxExtension[S, A](opt: AppliedTraversal[S, A]) {
def indexFocus[I, A1](i: I)(implicit
evIndex: monocle.function.Index[A, I, A1]
): AppliedTraversal[S, A1] = opt.index(i)
def lastFocus[A1](implicit ev: Last[A, A1]) = opt.andThen(ev.last)
def headFocus[A1](implicit ev: Head[A, A1]) = opt.andThen(ev.head)
}
implicit class AppliedPTraversalSyntaxExtension[S, T, A, B](opt: AppliedPTraversal[S, T, A, B]) {
def right[L, A1, B1](implicit
evA: A =:= Either[L, A1],
evB: B =:= Either[L, B1],
): AppliedPTraversal[S, T, A1, B1] = {
val adapted: monocle.PTraversal[S, T, Either[L, A1], Either[L, B1]] =
evB.substituteCo[monocle.PTraversal[S, T, Either[L, A1], *]](
evA.substituteCo[monocle.PTraversal[S, T, *, B]](opt.optic)
)
val prism = monocle.std.either.pStdRight[L, A1, B1]
AppliedPTraversal(opt.value, adapted.andThen(prism))
}
def left[R, A1, B1](implicit
evA: A =:= Either[A1, R],
evB: B =:= Either[B1, R],
): AppliedPTraversal[S, T, A1, B1] = {
val adapted: monocle.PTraversal[S, T, Either[A1, R], Either[B1, R]] =
evB.substituteCo[monocle.PTraversal[S, T, Either[A1, R], *]](
evA.substituteCo[monocle.PTraversal[S, T, *, B]](opt.optic)
)
val prism = monocle.std.either.pStdLeft[A1, R, B1]
AppliedPTraversal(opt.value, adapted.andThen(prism))
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment