Code Monkey home page Code Monkey logo

Comments (11)

mpilquist avatar mpilquist commented on May 18, 2024 1

:) I feel like the expectation mismatch leads to https://github.com/quchen/articles/blob/master/monad_fail.md.

Anyway, I'm πŸ‘ on a SemigroupK[IO] as proposed.

from cats-effect.

fommil avatar fommil commented on May 18, 2024
  implicit val IOPlus: SemigroupK[IO] = new SemigroupK[IO] {
    def combineK[A](x: IO[A], y: IO[A]): IO[A] = x.handleErrorWith(_ => y)
  }

from cats-effect.

fommil avatar fommil commented on May 18, 2024

There was a horrid suggestion on the gitter channel to provide an Alternative by returning a failed IO as empty. I guess that works.

from cats-effect.

alexandru avatar alexandru commented on May 18, 2024

For Strings the concatenation operation makes the canonical Semigroup / Monoid, same for Lists.

Not having a problem with adding a SemigroupK[IO], however given that we try to be coherent in our type-class definitions, I'm not sure what makes x.handleErrorWith(_ => y) canonical. It's not very obvious to me, especially the IO[A] values aren't both evaluated.

A more obvious definition for me would be something that evaluates both:

x.flatMap(_ => y)

x.flatMap(x => y.map(_ => x))

But maybe this isn't obvious enough either. More obvious is Semigroup[IO[A]] for any A : Semigroup[A], which is already defined.

So I'm not sure how to help. Somebody more knowledgeable with this stuff needs to comment.

from cats-effect.

alexandru avatar alexandru commented on May 18, 2024

Also, I'm not sure if my expectation for evaluating both helps, since you want "OR logic", with short-circuiting, so I'm assuming that evaluating both is precisely what you don't want?

I guess that what I'm asking is why would anybody expect x.handleErrorWith(_ => y) to be the implementation of a SemigroupK[IO]?

Is there some theory or precedent in other libraries?

from cats-effect.

fommil avatar fommil commented on May 18, 2024

Plus (or as cats have renamed it, SemigroupK) has "pick the first winner, ignore errors" semantics. Although it is not expressed in its laws.

from cats-effect.

alexandru avatar alexandru commented on May 18, 2024

Semigroup comes from category theory, I'm only familiar with the laws I learned in my 12th grade β€” kids in Romania learn about semigroups and monoids in high-school, guess we got lucky πŸ˜€

Those semantics are interesting. If that's the case, guess it makes sense, but are there examples of such instances in other libraries? Cats, Scalaz, Haskell, PureScript? If this can be expected given prior work, then we could have a SemigroupK[IO] instance.

I know that issues aren't for tutoring, but I saw this issue lingering since a week ago, so I'm asking in absence of somebody else more knowledgeable confirming this.

from cats-effect.

mpilquist avatar mpilquist commented on May 18, 2024

Plus (or as cats have renamed it, SemigroupK) has "pick the first winner, ignore errors" semantics. Although it is not expressed in its laws.

This is a property of certain lawful instances but not of the type class itself. The type class only defines a universally quantified associative combine operation. For example, consider MonoidK[List].

from cats-effect.

mpilquist avatar mpilquist commented on May 18, 2024

Here's another example which is more fundamental:

implicit def semigroupKConst[A](implicit A: Semigroup[A]): SemigroupK[Const[A,?]] = new SemigroupK[Const[A,?]] {
  def combineK[B](x: Const[A,B], y: Const[A,B]): Const[A,B] = Const(A.combine(x.getConst, y.getConst))
}

from cats-effect.

rossabaker avatar rossabaker commented on May 18, 2024

I thought the "pick the first winner, ignore errors" semantics might be expected whenever there is an ApplicativeError to define a "winner". Not always:

scala> def law[F[_]](implicit AE: ApplicativeError[F, String], SK: SemigroupK[F], A: Arbitrary[F[Int]]) = forAll { (e1: F[Int], e2: F[Int]) => e1.handleErrorWith(_ => e2) == e1 <+> e2 }.check
law: [F[_]](implicit AE: cats.ApplicativeError[F,String], implicit SK: cats.SemigroupK[F], implicit A: org.scalacheck.Arbitrary[F[Int]])Unit

scala> law[Either[String, ?]]
+ OK, passed 100 tests.

scala> law[EitherT[List, String, ?]]
+ OK, passed 100 tests.

scala> law[OptionT[Either[String, ?], ?]]
! Falsified after 0 passed tests.
> ARG_0: OptionT(Right(None))
> ARG_1: OptionT(Left())

from cats-effect.

fommil avatar fommil commented on May 18, 2024

well, yes, I guess it's more like "pick the first winner, ignoring failures, unless there are no winners. then we all lose"

from cats-effect.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.