-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Replace Split with Commutative Arrow. Continuing #1719 #1766
Replace Split with Commutative Arrow. Continuing #1719 #1766
Conversation
5cfef8c
to
23425dc
Compare
My review is at the moment to use |
Codecov Report
@@ Coverage Diff @@
## master #1766 +/- ##
==========================================
- Coverage 95.41% 95.26% -0.16%
==========================================
Files 256 265 +9
Lines 4207 4283 +76
Branches 90 97 +7
==========================================
+ Hits 4014 4080 +66
- Misses 193 203 +10
Continue to review full report at Codecov.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall this is excellent, though I fear we're missing an instance (or two, see my other comment); CommutativeMonad[WriterT[F, L, ?]]
where there's a CommutativeMonad[F]
and CommutativeMonoid[L]
.
If we introduce CommutativeCartesian
and friends we'll also have an instance of that Validated[E, ?]
given CommutativeSemigroup[E]
... but I don't see it being necessary in this PR.
/** | ||
* Must obey the laws defined in cats.laws.ArrowLaws. | ||
*/ | ||
@typeclass trait Arrow[F[_, _]] extends Category[F] with Strong[F] { self => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
* Lift a function into the context of an Arrow. | ||
* | ||
* In the reference articles "Arrows are Promiscuous...", and in the corresponding Haskell | ||
* library `Control.Arrow`, this function is called `arr`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
@@ -20,6 +26,25 @@ import simulacrum.typeclass | |||
compose(swap, compose(first[A, B, C](fa), swap)) | |||
} | |||
|
|||
override def split[A, B, C, D](f: F[A, B], g: F[C, D]): F[(A, C), (B, D)] = | |||
/** |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
implicit val catsDataArrowForKleisliId: Arrow[Kleisli[Id, ?, ?]] = | ||
catsDataArrowForKleisli[Id] | ||
implicit val catsDataCommutativeArrowForKleisliId: CommutativeArrow[Kleisli[Id, ?, ?]] = | ||
catsDataCommutativeArrowForKleisli[Id] | ||
|
||
implicit def catsDataMonadReaderForKleisliId[A]: MonadReader[Kleisli[Id, A, ?], A] = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Kleisli[F, A, B]
is seemingly a commutative monad now too, given F[_]: CommutativeMonad
. ReaderT
has no added effects, so I think this has to be the case.
This commit removes from the `core` module the `Split` typeclass. This includes the following changes: * The `Arrow` typeclass is no longer a subtype of `Split`. * The `split` operation, previously in the `Split` typeclass, is now integrated in the `Arrow` typeclass, with a default implementation. * Following notation from the `Control.Arrow` library for Haskell, we use the operator `***` as an alias for `split`. * `SplitSyntax` is replaced with `ArrowSyntax`. * We remove the `SplitLaws` and the `SplitTests`. In consequence, ArrowLaws does not inherit from SplitLaws anymore. * We modify the instances for `Kleisli`. We remove the trait `KleisliSpli`, and we replace the _factory_ method that was generating it to generate a `KleisliCompose` instead. * We remove the tests on the `SplitLaws` for Kleisli and CoKleisli
We add a type-class of commutative arrows, which are those in which the `split` operation is commutative (can pair in any order).
We introduce a Commutative Monad Type-class, a subclass of Monad in which the flatMap of independent operations is commutative.
We introduce some instances of CommutativeArrow for Kleisli, which are based on CommutativeMonad.
We introduce a new type class, CommutativeFlatMap, to load the commutativity law one level up.
We introduce the duals of Commutative Comonads and CoflatMap, as the duals of commutative Flatmaps and Monads. This is done to generate and test CommutativeArrow instances for the Cokleisli datatype.
We complete the tests for the CommutativeArrow instance of Cokleisli. To use it, we mark the Monad instance of `NonEmptyList` as a Commutative Monad.
ebf2e0e
to
c5ab4a5
Compare
@edmundnoble you are right, both are |
Do we now if there are other We can also make the |
import cats.data.{NonEmptyList, NonEmptyVector} | ||
import cats.laws.discipline.{ComonadTests, MonadTests, NonEmptyTraverseTests, ReducibleTests, SemigroupKTests, SerializableTests} | ||
import cats.laws.discipline.{SemigroupKTests, MonadTests, SerializableTests, NonEmptyTraverseTests, ReducibleTests, ComonadTests} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we can leave these alphabetically?
@@ -238,9 +254,8 @@ class KleisliTests extends CatsSuite { | |||
MonadReader[Reader[Int, ?], Int] | |||
Monoid[Reader[Int, String]] | |||
MonoidK[λ[α => Reader[α, α]]] | |||
Arrow[Reader[?, ?]] | |||
CommutativeArrow[Reader[?, ?]] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can leave Arrow[Reader[?, ?]]
here (move it below CommutativeArrow
).
We can add Arrow[Kleisli[Id, ?, ?]]
above as well.
@peterneyens I made function1 also commutative and correct the tests. |
The I was just thinking that if we can't come up with other instances, adding I think this PR is good to be merged 👍 (thanks @diesalbla and @kailuowang) ; I just wanted to hear other opinions if |
Agreed with @peterneyens, I'd need at least one example of a commutative comonad/coflatmap before adding that but otherwise 👍 for merging. |
@peterneyens you are right, it was Update: Removed |
|
||
checkAll("Cokleisli[Id, Int, Int]", CommutativeArrowTests[Cokleisli[Id, ?, ?]].commutativeArrow[Int, Int, Int, Int, Int, Int]) | ||
checkAll("CommutativeArrow[Cokleisli[Id, ?, ?]]", SerializableTests.serializable(CommutativeArrow[Cokleisli[Id, ?, ?]])) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we need to add a test for Cokleisli[F, ?, ?]
as well (maybe the existing one using NonEmptyList
)?
Nitpicking, can we put these CommutativeArrow
tests not between the MonoidK
and SemigroupK
tests?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
addressed.
Regarding |
merging with 2 sign-offs |
per conversation with @diesalbla, this it the PR attempting to complete #1719