Skip to content

Commit

Permalink
Prisms for Either (#2877)
Browse files Browse the repository at this point in the history
Co-authored-by: Simon Vergauwen <nomisRev@users.noreply.github.com>
  • Loading branch information
serras and nomisRev authored Jan 9, 2023
1 parent 4a8e88d commit a5a867f
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 0 deletions.
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())

0 comments on commit a5a867f

Please sign in to comment.