Created
August 24, 2023 11:53
-
-
Save GrafBlutwurst/b640837399bc44898700129274e741ec to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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