All Downloads are FREE. Search and download functionalities are using the official Maven repository.

crystal.package.scala Maven / Gradle / Ivy

There is a newer version: 0.45.2
Show newest version
// Copyright (c) 2016-2023 Association of Universities for Research in Astronomy, Inc. (AURA)
// For license information see LICENSE or https://opensource.org/licenses/BSD-3-Clause

package crystal

import cats.Applicative
import cats.Eq
import cats.InvariantSemigroupal
import cats.Monad
import cats.syntax.all.*

export syntax.*

extension [F[_]: Monad](f: F[Unit])
  def when(cond: F[Boolean]): F[Unit] =
    cond.flatMap(f.whenA)

extension [F[_]: Applicative](opt: Option[F[Unit]])
  def orUnit: F[Unit] =
    opt.getOrElse(Applicative[F].unit)

object throwable {
  // Copied from cats-effect-laws utils.
  given Eq[Throwable] =
    new Eq[Throwable] {
      def eqv(x: Throwable, y: Throwable): Boolean =
        // All exceptions are non-terminating and given exceptions
        // aren't values (being mutable, they implement reference
        // equality), then we can't really test them reliably,
        // especially due to race conditions or outside logic
        // that wraps them (e.g. ExecutionException)
        (x ne null) == (y ne null)
    }
}

given [F[_]: Monad]: InvariantSemigroupal[ViewF[F, *]] with
  def product[A, B](fa: ViewF[F, A], fb: ViewF[F, B]): ViewF[F, (A, B)] =
    ViewF.apply(
      fa.get -> fb.get,
      (f, cb) =>
        fa.modCB( // Get current a value
          identity(_),
          oldA =>
            fb.modCB( // Get current b value
              identity(_),
              oldB =>
                fa.modCB( // Modify underlying a value
                  a => f(a, oldB)._1,
                  (prevA, newA) =>
                    fb.modCB( // Modify underlying b value
                      b => f(oldA, b)._2,
                      (prevB, newB) => cb((prevA, prevB), (newA, newB))
                    )
                )
            )
        )
    )

  def imap[A, B](fa: ViewF[F, A])(f: A => B)(g: B => A): ViewF[F, B] =
    fa.zoom(f)(mod => a => g(mod(f(a))))




© 2015 - 2024 Weber Informatics LLC | Privacy Policy