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

Prisms for Either #2877

Merged
merged 8 commits into from
Jan 9, 2023
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions arrow-libs/optics/arrow-optics/api/arrow-optics.api
Original file line number Diff line number Diff line change
Expand Up @@ -598,13 +598,17 @@ public final class arrow/optics/POptionalGetter$DefaultImpls {
public abstract interface class arrow/optics/PPrism : arrow/optics/PEvery, arrow/optics/POptional, arrow/optics/POptionalGetter, arrow/optics/PSetter, arrow/optics/PTraversal {
public static final field Companion Larrow/optics/PPrism$Companion;
public abstract fun compose (Larrow/optics/PPrism;)Larrow/optics/PPrism;
public static fun eitherLeft ()Larrow/optics/PPrism;
public static fun eitherRight ()Larrow/optics/PPrism;
public abstract fun first ()Larrow/optics/PPrism;
public abstract fun foldMap (Larrow/typeclasses/Monoid;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
public abstract fun getOrModify (Ljava/lang/Object;)Larrow/core/Either;
public abstract fun left ()Larrow/optics/PPrism;
public abstract fun liftNullable (Lkotlin/jvm/functions/Function1;)Lkotlin/jvm/functions/Function1;
public abstract fun modify (Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
public static fun none ()Larrow/optics/PPrism;
public static fun pLeft ()Larrow/optics/PPrism;
public static fun pRight ()Larrow/optics/PPrism;
public static fun pSome ()Larrow/optics/PPrism;
public abstract fun plus (Larrow/optics/PPrism;)Larrow/optics/PPrism;
public abstract fun reverseGet (Ljava/lang/Object;)Ljava/lang/Object;
Expand All @@ -615,11 +619,15 @@ public abstract interface class arrow/optics/PPrism : arrow/optics/PEvery, arrow
}

public final class arrow/optics/PPrism$Companion {
public final fun eitherLeft ()Larrow/optics/PPrism;
public final fun eitherRight ()Larrow/optics/PPrism;
public final fun id ()Larrow/optics/PIso;
public final fun invoke (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)Larrow/optics/PPrism;
public final fun none ()Larrow/optics/PPrism;
public final fun only (Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Larrow/optics/PPrism;
public static synthetic fun only$default (Larrow/optics/PPrism$Companion;Ljava/lang/Object;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Larrow/optics/PPrism;
public final fun pLeft ()Larrow/optics/PPrism;
public final fun pRight ()Larrow/optics/PPrism;
public final fun pSome ()Larrow/optics/PPrism;
public final fun some ()Larrow/optics/PPrism;
}
Expand Down Expand Up @@ -813,6 +821,15 @@ public final class arrow/optics/dsl/AtKt {
public static final fun at (Larrow/optics/PTraversal;Larrow/optics/typeclasses/At;Ljava/lang/Object;)Larrow/optics/PTraversal;
}

public final class arrow/optics/dsl/EitherKt {
public static final fun getLeft (Larrow/optics/POptional;)Larrow/optics/POptional;
public static final fun getLeft (Larrow/optics/PPrism;)Larrow/optics/PPrism;
public static final fun getLeft (Larrow/optics/PTraversal;)Larrow/optics/PTraversal;
public static final fun getRight (Larrow/optics/POptional;)Larrow/optics/POptional;
public static final fun getRight (Larrow/optics/PPrism;)Larrow/optics/PPrism;
public static final fun getRight (Larrow/optics/PTraversal;)Larrow/optics/PTraversal;
}

public final class arrow/optics/dsl/EveryKt {
public static final fun every (Larrow/optics/Fold;Larrow/optics/PEvery;)Larrow/optics/Fold;
public static final fun every (Larrow/optics/PIso;Larrow/optics/PEvery;)Larrow/optics/PEvery;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ import arrow.core.Some
import arrow.core.compose
import arrow.core.flatMap
import arrow.core.identity
import arrow.core.left
import arrow.core.right
import arrow.typeclasses.Monoid
import kotlin.jvm.JvmName
import kotlin.jvm.JvmStatic

/**
Expand Down Expand Up @@ -172,6 +175,48 @@ public interface PPrism<S, T, A, B> : POptional<S, T, A, B>, PSetter<S, T, A, B>
getOrModify = { option -> option.fold({ Either.Right(Unit) }, { Either.Left(option) }) },
reverseGet = { _ -> None }
)

/**
* [Prism] to focus into an [arrow.core.Either.Left]
*/
@JvmStatic @JvmName("eitherLeft")
public fun <L, R> left(): Prism<Either<L, R>, L> = pLeft()

/**
* [Prism] to focus into an [arrow.core.Either.Right]
*/
@JvmStatic @JvmName("eitherRight")
public fun <L, R> right(): Prism<Either<L, R>, R> = pRight()

/**
* Polymorphic [PPrism] to focus into an [arrow.core.Either.Left]
*/
@JvmStatic
public fun <L, R, E> pLeft(): PPrism<Either<L, R>, Either<E, R>, L, E> =
Prism(
getOrModify = { e ->
when (e) {
is Either.Left -> e.value.right()
is Either.Right -> e.left()
}
},
reverseGet = { it.left() }
)

/**
* Polymorphic [PPrism] to focus into an [arrow.core.Either.Right]
*/
@JvmStatic
public fun <L, R, B> pRight(): PPrism<Either<L, R>, Either<L, B>, R, B> =
PPrism(
getOrModify = { e ->
when (e) {
is Either.Left -> e.left()
is Either.Right -> e.value.right()
}
},
reverseGet = { it.right() }
)
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package arrow.optics.dsl

import arrow.core.Either
import arrow.optics.Lens
import arrow.optics.Optional
import arrow.optics.PPrism
import arrow.optics.Prism
import arrow.optics.Traversal

/**
* DSL to compose a [Prism] with focus [Either] with a [Prism] with a focus of [Either.Left]<[L]>
*
* @receiver [Prism] with a focus in [Either]
* @return [Prism] with a focus in [L]
*/
public inline val <A, L, R> Prism<A, Either<L, R>>.left: Prism<A, L> inline get() = this.compose(PPrism.left())

/**
* DSL to compose a [Optional] with focus [Either] with a [Prism] with a focus of [Either.Left]<[L]>
*
* @receiver [Lens] or [Optional] with a focus in [Either]
* @return [Optional] with a focus in [L]
*/
public inline val <A, L, R> Optional<A, Either<L, R>>.left: Optional<A, L> inline get() = this.compose(PPrism.left())

/**
* DSL to compose a [Traversal] with focus [Either] with a [Prism] with a focus of [Either.Left]<[L]>
*
* @receiver [Traversal] with a focus in [Either]
* @return [Traversal] with a focus in [L]
*/
public inline val <A, L, R> Traversal<A, Either<L, R>>.left: Traversal<A, L> inline get() = this.compose(PPrism.left())

/**
* DSL to compose a [Prism] with focus [Either] with a [Prism] with a focus of [Either.Right]<[R]>
*
* @receiver [Prism] with a focus in [Either]
* @return [Prism] with a focus in [R]
*/
public inline val <A, L, R> Prism<A, Either<L, R>>.right: Prism<A, R> inline get() = this.compose(PPrism.right())

/**
* DSL to compose a [Optional] with focus [Either] with a [Prism] with a focus of [Either.Right]<[R]>
*
* @receiver [Lens] or [Optional] with a focus in [Either]
* @return [Optional] with a focus in [R]
*/
public inline val <A, L, R> Optional<A, Either<L, R>>.right: Optional<A, R> inline get() = this.compose(PPrism.right())

/**
* DSL to compose a [Traversal] with focus [Either] with a [Prism] with a focus of [Either.Right]<[R]>
*
* @receiver [Traversal] with a focus in [Either]
* @return [Traversal] with a focus in [R]
*/
public inline val <A, L, R> Traversal<A, Either<L, R>>.right: Traversal<A, R> inline get() = this.compose(PPrism.right())