Skip to content

Commit 756eaad

Browse files
committed
add Either syntax
1 parent f910717 commit 756eaad

3 files changed

Lines changed: 70 additions & 1 deletion

File tree

core/src/main/scala/cats/mtl/syntax/all.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,4 @@ trait AllSyntax
2828
with HandleSyntax
2929
with ChronicleSyntax
3030
with OptionSyntax
31+
with EitherSyntax
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
* Copyright 2021 Typelevel
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package cats
18+
package mtl
19+
package syntax
20+
21+
object either extends EitherSyntax
22+
23+
private[mtl] trait EitherSyntax {
24+
implicit def catsMtsSyntaxToEitherOps[A, B](oa: Either[A, B]): EitherOps[A, B] =
25+
new EitherOps[A, B](oa)
26+
}
27+
28+
final class EitherOps[A, B] private[mtl] (private val self: Either[A, B]) extends AnyVal {
29+
30+
/**
31+
* Lifts `Either[A, B]` to `F[B]` as long as there's `Raise[F, A]` in the scope and `F` is an
32+
* `Applicative`.
33+
*
34+
* @note
35+
* method `.rescue` in the example requires `ApplicativeError[F, E]` instance.
36+
*
37+
* @example
38+
* (Scala 3)
39+
* {{{
40+
* import scala.util.*
41+
* import cats.mtl.*, syntax.either.*
42+
*
43+
* case class MyErr(err: String) extends Exception(err)
44+
*
45+
* val res1 =
46+
* Handle.allow:
47+
* Right[String, Int](123).liftTo[Try]
48+
* .rescue: err =>
49+
* Failure(MyErr(err))
50+
*
51+
* assertEquals(res1, Success(123))
52+
*
53+
* val res2 =
54+
* Handle.allow:
55+
* Left[String, Int]("OOPS").liftTo[Try]
56+
* .rescue: err =>
57+
* Failure(MyErr(err))
58+
*
59+
* assertEquals(res2, Failure("OOPS"))
60+
* }}}
61+
*/
62+
def liftTo[F[_]](implicit F: Applicative[F], raise: Raise[F, A]): F[B] =
63+
raise.fromEither(self)
64+
}

tests/shared/src/test/scala/cats/mtl/tests/Syntax.scala

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,12 @@ final class Syntax extends BaseSuite {
7878
raise: Raise[F, Foo]): Unit = {
7979

8080
val _ = (
81+
// cats.mtl.syntax.option.*
8182
Some("abc").liftTo[F](Bar(123)): F[String],
82-
Some(Bar(456)).raiseTo[F]: F[Unit]
83+
Some(Bar(456)).raiseTo[F]: F[Unit],
84+
// cats.mtl.syntax.either.*
85+
Left[Bar, String](Bar(789)).liftTo[F]: F[String],
86+
Right[Bar, String]("def").liftTo[F]: F[String]
8387
)
8488
}
8589

0 commit comments

Comments
 (0)