Skip to content

Commit

Permalink
Merge pull request #5 from armanbilge/local
Browse files Browse the repository at this point in the history
Add Local via IOLocal
  • Loading branch information
bplommer authored Feb 17, 2022
2 parents 3c14985 + a9f0cbf commit d275a9e
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 6 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ A microlibrary of [MTL](https://github.com/typelevel/cats-mtl) typeclasses and i

* `oxidized-kernel`: `ConcurrentStateful` typeclass that relaxes the laws of `Stateful`
* `oxidized-std`: `ConcurrentStateful` for `F` via a `Ref`
* `oxidized`: all of the above, plus `Raise` and `Stateful` via an `IOLocal` for `IO`
* `oxidized`: all of the above, plus `Raise`, `Local` and `Stateful` via an `IOLocal` for `IO`
17 changes: 13 additions & 4 deletions core/src/main/scala/oxidized/instances/io.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,10 @@

package oxidized.instances

import cats.mtl.Stateful
import cats.mtl.{Local, Raise, Stateful}
import cats.effect.IO
import cats.Monad
import cats.{Applicative, Functor, Monad}
import cats.effect.IOLocal
import cats.mtl.Raise
import cats.Functor

object io extends IOInstances

Expand All @@ -33,6 +31,17 @@ trait IOInstances {
override def set(s: A): IO[Unit] = local.set(s)
}

implicit def catsMtlEffectLocalForIO[E](implicit ioLocal: IOLocal[E]): Local[IO, E] =
new Local[IO, E] {
override def local[A](fa: IO[A])(f: E => E): IO[A] = ioLocal.get.flatMap { initial =>
ioLocal.set(f(initial)) >> fa.guarantee(ioLocal.set(initial))
}

override def applicative: Applicative[IO] = IO.asyncForIO

override def ask[E2 >: E]: IO[E2] = ioLocal.get
}

implicit def catsMtlEffectRaiseForIO: Raise[IO, Throwable] =
new Raise[IO, Throwable] {
override def functor: Functor[IO] = IO.asyncForIO
Expand Down
3 changes: 2 additions & 1 deletion core/src/test/scala/oxidized/instances/IOSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
package oxidized.instances

import cats.effect.testkit.TestInstances
import cats.mtl.laws.discipline.{HandleTests, StatefulTests}
import cats.mtl.laws.discipline.{HandleTests, LocalTests, StatefulTests}
import cats.effect.IOLocal
import cats.effect.IO
import org.specs2.mutable.Specification
Expand All @@ -35,6 +35,7 @@ class IOSpec extends Specification with Discipline with TestInstances {
case _ => throw new RuntimeException
}
checkAll("Stateful[IO]", StatefulTests[IO, Int].stateful)
checkAll("Local[IO]", LocalTests[IO, Int].local[Int, Int])
checkAll("Handle[IO]", HandleTests[IO, Throwable].handle[Int])

}

0 comments on commit d275a9e

Please sign in to comment.