-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Implement effect-polymorphic class atop STM #791 * Implement effect-polymorphic TRef #791 * remove unnecessary type parameters #791 * Add 'FunctionK' instance for converting TaskR to cats.IO #791 * Link to original documentation #791 * More efficient `collectAll` #791 * Make every method final #791 * Revert: Add 'FunctionK' instance for converting TaskR to cats.IO #791 (37d17db) * Push implicits down to atomically #791 * Reorder methods alphabetically #791 * Fix formatting #791
- Loading branch information
1 parent
99e699e
commit fb7b0f1
Showing
2 changed files
with
298 additions
and
0 deletions.
There are no files selected for viewing
226 changes: 226 additions & 0 deletions
226
interop-cats/jvm/src/main/scala/scalaz/zio/interop/stm/STM.scala
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,226 @@ | ||
/* | ||
* Copyright 2017-2019 John A. De Goes and the ZIO Contributors | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package scalaz.zio.interop.stm | ||
|
||
import cats.effect.Async | ||
import scalaz.zio.stm.{ STM => ZSTM } | ||
import scalaz.zio.Runtime | ||
|
||
import scala.util.Try | ||
|
||
/** | ||
* See [[scalaz.zio.stm.STM]] | ||
*/ | ||
final class STM[F[+ _], +A] private[stm] (private[stm] val underlying: ZSTM[Throwable, A]) { | ||
self => | ||
|
||
/** | ||
* See `<*>` [[scalaz.zio.stm.STM]] `<*>` | ||
*/ | ||
final def <*>[B](that: => STM[F, B]): STM[F, (A, B)] = | ||
self zip that | ||
|
||
/** | ||
* See [[scalaz.zio.stm.STM]] `<*` | ||
*/ | ||
final def <*[B](that: => STM[F, B]): STM[F, A] = | ||
self zipLeft that | ||
|
||
/** | ||
* See [[scalaz.zio.stm.STM]] `*>` | ||
*/ | ||
final def *>[B](that: => STM[F, B]): STM[F, B] = | ||
self zipRight that | ||
|
||
/** | ||
* See [[scalaz.zio.stm.STM]] `>>=` | ||
*/ | ||
final def >>=[B](f: A => STM[F, B]): STM[F, B] = | ||
self flatMap f | ||
|
||
/** | ||
* See [[scalaz.zio.stm.STM#collect]] | ||
*/ | ||
final def collect[B](pf: PartialFunction[A, B]): STM[F, B] = new STM(underlying.collect(pf)) | ||
|
||
/** | ||
* See [[scalaz.zio.stm.STM#commit]] | ||
*/ | ||
final def commit(implicit R: Runtime[Any], A: Async[F]): F[A] = STM.atomically(self) | ||
|
||
/** | ||
* See [[scalaz.zio.stm.STM#const]] | ||
*/ | ||
final def const[B](b: => B): STM[F, B] = self map (_ => b) | ||
|
||
/** | ||
* See [[scalaz.zio.stm.STM#either]] | ||
*/ | ||
final def either: STM[F, Either[Throwable, A]] = new STM(underlying.either) | ||
|
||
/** | ||
* See [[scalaz.zio.stm.STM#filter]] | ||
*/ | ||
final def filter(f: A => Boolean): STM[F, A] = | ||
collect { | ||
case a if f(a) => a | ||
} | ||
|
||
/** | ||
* See [[scalaz.zio.stm.STM#flatMap]] | ||
*/ | ||
final def flatMap[B](f: A => STM[F, B]): STM[F, B] = new STM(underlying.flatMap(f.andThen(_.underlying))) | ||
|
||
/** | ||
* See [[scalaz.zio.stm.STM#flatten]] | ||
*/ | ||
final def flatten[B](implicit ev: A <:< STM[F, B]): STM[F, B] = | ||
self flatMap ev | ||
|
||
/** | ||
* See [[scalaz.zio.stm.STM#fold]] | ||
*/ | ||
final def fold[B](f: Throwable => B, g: A => B): STM[F, B] = new STM(underlying.fold(f, g)) | ||
|
||
/** | ||
* See [[scalaz.zio.stm.STM#foldM]] | ||
*/ | ||
final def foldM[B](f: Throwable => STM[F, B], g: A => STM[F, B]): STM[F, B] = | ||
new STM(underlying.foldM(f.andThen(_.underlying), g.andThen(_.underlying))) | ||
|
||
/** | ||
* See [[scalaz.zio.stm.STM#map]] | ||
*/ | ||
final def map[B](f: A => B): STM[F, B] = new STM(underlying.map(f)) | ||
|
||
/** | ||
* See [[scalaz.zio.stm.STM#mapError]] | ||
*/ | ||
final def mapError[E1 <: Throwable](f: Throwable => E1): STM[F, A] = new STM(underlying.mapError(f)) | ||
|
||
/** | ||
* Switch from effect F to effect G. | ||
*/ | ||
final def mapK[G[+ _]]: STM[G, A] = new STM(underlying) | ||
|
||
/** | ||
* See [[scalaz.zio.stm.STM#option]] | ||
*/ | ||
final def option: STM[F, Option[A]] = | ||
fold[Option[A]](_ => None, Some(_)) | ||
|
||
/** | ||
* See [[scalaz.zio.stm.STM#orElse]] | ||
*/ | ||
final def orElse[A1 >: A](that: => STM[F, A1]): STM[F, A1] = new STM(underlying.orElse(that.underlying)) | ||
|
||
/** | ||
* See [[scalaz.zio.stm.STM#orElseEither]] | ||
*/ | ||
final def orElseEither[B](that: => STM[F, B]): STM[F, Either[A, B]] = | ||
(self map (Left[A, B](_))) orElse (that map (Right[A, B](_))) | ||
|
||
/** | ||
* See scalaz.zio.stm.STM.unit | ||
*/ | ||
final def unit: STM[F, Unit] = const(()) | ||
|
||
/** | ||
* See scalaz.zio.stm.STM.unit | ||
*/ | ||
final def void: STM[F, Unit] = unit | ||
|
||
/** | ||
* Same as [[filter]] | ||
*/ | ||
final def withFilter(f: A => Boolean): STM[F, A] = filter(f) | ||
|
||
/** | ||
* See [[scalaz.zio.stm.STM#zip]] | ||
*/ | ||
final def zip[B](that: => STM[F, B]): STM[F, (A, B)] = | ||
(self zipWith that)((a, b) => a -> b) | ||
|
||
/** | ||
* See [[scalaz.zio.stm.STM#zipLeft]] | ||
*/ | ||
final def zipLeft[B](that: => STM[F, B]): STM[F, A] = | ||
(self zip that) map (_._1) | ||
|
||
/** | ||
* See [[scalaz.zio.stm.STM#zipRight]] | ||
*/ | ||
final def zipRight[B](that: => STM[F, B]): STM[F, B] = | ||
(self zip that) map (_._2) | ||
|
||
/** | ||
* See [[scalaz.zio.stm.STM#zipWith]] | ||
*/ | ||
final def zipWith[B, C](that: => STM[F, B])(f: (A, B) => C): STM[F, C] = | ||
self flatMap (a => that map (b => f(a, b))) | ||
|
||
} | ||
|
||
object STM { | ||
|
||
final def atomically[F[+ _], A](stm: STM[F, A])(implicit R: Runtime[Any], A: Async[F]): F[A] = | ||
A.async { cb => | ||
R.unsafeRunAsync(ZSTM.atomically(stm.underlying)) { exit => | ||
cb(exit.toEither) | ||
} | ||
} | ||
|
||
final def check[F[+ _]](p: Boolean): STM[F, Unit] = | ||
if (p) STM.unit else retry | ||
|
||
final def collectAll[F[+ _], A]( | ||
i: Iterable[STM[F, A]] | ||
): STM[F, List[A]] = | ||
new STM(ZSTM.collectAll(i.map(_.underlying))) | ||
|
||
final def die[F[+ _]](t: Throwable): STM[F, Nothing] = | ||
succeedLazy(throw t) | ||
|
||
final def dieMessage[F[+ _]](m: String): STM[F, Nothing] = | ||
die(new RuntimeException(m)) | ||
|
||
final def fail[F[+ _]](e: Throwable): STM[F, Nothing] = | ||
new STM(ZSTM.fail(e)) | ||
|
||
final def foreach[F[+ _], A, B]( | ||
as: Iterable[A] | ||
)(f: A => STM[F, B]): STM[F, List[B]] = | ||
collectAll(as.map(f)) | ||
|
||
final def fromEither[F[+ _], A](e: Either[Throwable, A]): STM[F, A] = | ||
new STM(ZSTM.fromEither(e)) | ||
|
||
final def fromTry[F[+ _], A](a: => Try[A]): STM[F, A] = | ||
new STM(ZSTM.fromTry(a)) | ||
|
||
final def partial[F[+ _], A](a: => A): STM[F, A] = | ||
fromTry(Try(a)) | ||
|
||
final def retry[F[+ _]]: STM[F, Nothing] = new STM(ZSTM.retry) | ||
|
||
final def succeed[F[+ _], A](a: A): STM[F, A] = new STM(ZSTM.succeed(a)) | ||
|
||
final def succeedLazy[F[+ _], A](a: => A): STM[F, A] = | ||
new STM(ZSTM.succeedLazy(a)) | ||
|
||
final def unit[F[+ _]]: STM[F, Unit] = succeed(()) | ||
} |
72 changes: 72 additions & 0 deletions
72
interop-cats/jvm/src/main/scala/scalaz/zio/interop/stm/TRef.scala
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
/* | ||
* Copyright 2017-2019 John A. De Goes and the ZIO Contributors | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package scalaz.zio.interop.stm | ||
|
||
import cats.effect.Async | ||
import scalaz.zio.Runtime | ||
import scalaz.zio.stm.{ TRef => ZTRef } | ||
|
||
class TRef[F[+ _], A] private (val underlying: ZTRef[A]) extends AnyVal { | ||
self => | ||
|
||
/** | ||
* See [[scalaz.zio.stm.TRef#get]] | ||
*/ | ||
final def get: STM[F, A] = new STM(underlying.get) | ||
|
||
/** | ||
* Switch from effect F to effect G. | ||
*/ | ||
def mapK[G[+ _]]: TRef[G, A] = new TRef(underlying) | ||
|
||
/** | ||
* See [[scalaz.zio.stm.TRef#modify]] | ||
*/ | ||
final def modify[B](f: A => (B, A)): STM[F, B] = new STM(underlying.modify(f)) | ||
|
||
/** | ||
* See [[scalaz.zio.stm.TRef#modifySome]] | ||
*/ | ||
final def modifySome[B](default: B)(f: PartialFunction[A, (B, A)]): STM[F, B] = | ||
new STM(underlying.modifySome(default)(f)) | ||
|
||
/** | ||
* See [[scalaz.zio.stm.TRef#set]] | ||
*/ | ||
final def set(newValue: A): STM[F, Unit] = new STM(underlying.set(newValue)) | ||
|
||
override final def toString = underlying.toString | ||
|
||
/** | ||
* See [[scalaz.zio.stm.TRef#update]] | ||
*/ | ||
final def update(f: A => A): STM[F, A] = new STM(underlying.update(f)) | ||
|
||
/** | ||
* See [[scalaz.zio.stm.TRef#updateSome]] | ||
*/ | ||
final def updateSome(f: PartialFunction[A, A]): STM[F, A] = new STM(underlying.updateSome(f)) | ||
} | ||
|
||
object TRef { | ||
|
||
final def make[F[+ _], A](a: => A): STM[F, TRef[F, A]] = | ||
new STM(ZTRef.make(a).map(new TRef(_))) | ||
|
||
final def makeCommit[F[+ _], A](a: => A)(implicit R: Runtime[Any], A: Async[F]): F[TRef[F, A]] = | ||
STM.atomically(make(a)) | ||
} |