Skip to content
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

Rename SemigroupK.combine to combineK #781

Merged
merged 1 commit into from
Jan 30, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion core/src/main/scala/cats/MonadCombine.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@ import simulacrum.typeclass
*/
def unite[G[_], A](fga: F[G[A]])(implicit G: Foldable[G]): F[A] =
flatMap(fga) { ga =>
G.foldLeft(ga, empty[A])((acc, a) => combine(acc, pure(a)))
G.foldLeft(ga, empty[A])((acc, a) => combineK(acc, pure(a)))
}
}
2 changes: 1 addition & 1 deletion core/src/main/scala/cats/MonoidK.scala
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,6 @@ import simulacrum.typeclass
override def algebra[A]: Monoid[F[A]] =
new Monoid[F[A]] {
def empty: F[A] = self.empty
def combine(x: F[A], y: F[A]): F[A] = self.combine(x, y)
def combine(x: F[A], y: F[A]): F[A] = self.combineK(x, y)
}
}
6 changes: 3 additions & 3 deletions core/src/main/scala/cats/SemigroupK.scala
Original file line number Diff line number Diff line change
Expand Up @@ -26,21 +26,21 @@ import simulacrum.{op, typeclass}
* Combine two F[A] values.
*/
@op("<+>", alias=true)
def combine[A](x: F[A], y: F[A]): F[A]
def combineK[A](x: F[A], y: F[A]): F[A]

/**
* Compose two SemigroupK intsances.
*/
def compose[G[_]: SemigroupK]: SemigroupK[λ[α => F[G[α]]]] =
new SemigroupK[λ[α => F[G[α]]]] {
def combine[A](x: F[G[A]], y: F[G[A]]): F[G[A]] = self.combine(x, y)
def combineK[A](x: F[G[A]], y: F[G[A]]): F[G[A]] = self.combineK(x, y)
}

/**
* Given a type A, create a concrete Semigroup[F[A]].
*/
def algebra[A]: Semigroup[F[A]] =
new Semigroup[F[A]] {
def combine(x: F[A], y: F[A]): F[A] = self.combine(x, y)
def combine(x: F[A], y: F[A]): F[A] = self.combineK(x, y)
}
}
2 changes: 1 addition & 1 deletion core/src/main/scala/cats/arrow/Category.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ trait Category[F[_, _]] extends Compose[F] { self =>
override def algebraK: MonoidK[λ[α => F[α, α]]] =
new MonoidK[λ[α => F[α, α]]] {
def empty[A]: F[A, A] = id
def combine[A](f1: F[A, A], f2: F[A, A]): F[A, A] = self.compose(f1, f2)
def combineK[A](f1: F[A, A], f2: F[A, A]): F[A, A] = self.compose(f1, f2)
}

override def algebra[A]: Monoid[F[A, A]] =
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/scala/cats/arrow/Compose.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ trait Compose[F[_, _]] extends Serializable { self =>

def algebraK: SemigroupK[λ[α => F[α, α]]] =
new SemigroupK[λ[α => F[α, α]]] {
def combine[A](f1: F[A, A], f2: F[A, A]): F[A, A] = self.compose(f1, f2)
def combineK[A](f1: F[A, A], f2: F[A, A]): F[A, A] = self.compose(f1, f2)
}

def algebra[A]: Semigroup[F[A, A]] =
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/scala/cats/data/Cokleisli.scala
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ private trait CokleisliProfunctor[F[_]] extends Profunctor[Cokleisli[F, ?, ?]] {
private trait CokleisliSemigroupK[F[_]] extends SemigroupK[Lambda[A => Cokleisli[F, A, A]]] {
implicit def F: CoflatMap[F]

def combine[A](a: Cokleisli[F, A, A], b: Cokleisli[F, A, A]): Cokleisli[F, A, A] = a compose b
def combineK[A](a: Cokleisli[F, A, A], b: Cokleisli[F, A, A]): Cokleisli[F, A, A] = a compose b
}

private trait CokleisliMonoidK[F[_]] extends MonoidK[Lambda[A => Cokleisli[F, A, A]]] with CokleisliSemigroupK[F] {
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/scala/cats/data/Kleisli.scala
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ private trait KleisliMonoid[F[_], A, B] extends Monoid[Kleisli[F, A, B]] with Kl
private trait KleisliSemigroupK[F[_]] extends SemigroupK[Lambda[A => Kleisli[F, A, A]]] {
implicit def F: FlatMap[F]

override def combine[A](a: Kleisli[F, A, A], b: Kleisli[F, A, A]): Kleisli[F, A, A] = a compose b
override def combineK[A](a: Kleisli[F, A, A], b: Kleisli[F, A, A]): Kleisli[F, A, A] = a compose b
}

private trait KleisliMonoidK[F[_]] extends MonoidK[Lambda[A => Kleisli[F, A, A]]] with KleisliSemigroupK[F] {
Expand Down
12 changes: 6 additions & 6 deletions core/src/main/scala/cats/data/OneAnd.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,21 @@ final case class OneAnd[F[_], A](head: A, tail: F[A]) {
* Combine the head and tail into a single `F[A]` value.
*/
def unwrap(implicit F: MonadCombine[F]): F[A] =
F.combine(F.pure(head), tail)
F.combineK(F.pure(head), tail)

/**
* remove elements not matching the predicate
*/
def filter(f: A => Boolean)(implicit F: MonadCombine[F]): F[A] = {
val rest = F.filter(tail)(f)
if (f(head)) F.combine(F.pure(head), rest) else rest
if (f(head)) F.combineK(F.pure(head), rest) else rest
}

/**
* Append another OneAnd to this
*/
def combine(other: OneAnd[F, A])(implicit F: MonadCombine[F]): OneAnd[F, A] =
OneAnd(head, F.combine(tail, F.combine(F.pure(other.head), other.tail)))
OneAnd(head, F.combineK(tail, F.combineK(F.pure(other.head), other.tail)))

/**
* find the first element matching the predicate, if one exists
Expand Down Expand Up @@ -99,7 +99,7 @@ private[data] sealed trait OneAndInstances extends OneAndLowPriority1 {

implicit def oneAndSemigroupK[F[_]: MonadCombine]: SemigroupK[OneAnd[F, ?]] =
new SemigroupK[OneAnd[F, ?]] {
def combine[A](a: OneAnd[F, A], b: OneAnd[F, A]): OneAnd[F, A] =
def combineK[A](a: OneAnd[F, A], b: OneAnd[F, A]): OneAnd[F, A] =
a combine b
}

Expand All @@ -126,10 +126,10 @@ private[data] sealed trait OneAndInstances extends OneAndLowPriority1 {
def flatMap[A, B](fa: OneAnd[F, A])(f: A => OneAnd[F, B]): OneAnd[F, B] = {
val end = monad.flatMap(fa.tail) { a =>
val fa = f(a)
monad.combine(monad.pure(fa.head), fa.tail)
monad.combineK(monad.pure(fa.head), fa.tail)
}
val fst = f(fa.head)
OneAnd(fst.head, monad.combine(fst.tail, end))
OneAnd(fst.head, monad.combineK(fst.tail, end))
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions core/src/main/scala/cats/data/Prod.scala
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,8 @@ sealed trait ProdApplicative[F[_], G[_]] extends Applicative[Lambda[X => Prod[F,
sealed trait ProdSemigroupK[F[_], G[_]] extends SemigroupK[Lambda[X => Prod[F, G, X]]] {
def F: SemigroupK[F]
def G: SemigroupK[G]
override def combine[A](x: Prod[F, G, A], y: Prod[F, G, A]): Prod[F, G, A] =
Prod(F.combine(x.first, y.first), G.combine(x.second, y.second))
override def combineK[A](x: Prod[F, G, A], y: Prod[F, G, A]): Prod[F, G, A] =
Prod(F.combineK(x.first, y.first), G.combineK(x.second, y.second))
}

sealed trait ProdMonoidK[F[_], G[_]] extends MonoidK[Lambda[X => Prod[F, G, X]]] with ProdSemigroupK[F, G] {
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/scala/cats/data/Streaming.scala
Original file line number Diff line number Diff line change
Expand Up @@ -866,7 +866,7 @@ private[data] sealed trait StreamingInstances extends StreamingInstances1 {
as.flatMap(f)
def empty[A]: Streaming[A] =
Streaming.empty
def combine[A](xs: Streaming[A], ys: Streaming[A]): Streaming[A] =
def combineK[A](xs: Streaming[A], ys: Streaming[A]): Streaming[A] =
xs ++ ys

override def map2[A, B, Z](fa: Streaming[A], fb: Streaming[B])(f: (A, B) => Z): Streaming[Z] =
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/scala/cats/data/StreamingT.scala
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,7 @@ private[data] sealed trait StreamingTInstances extends StreamingTInstances1 {
fa.flatMap(f)
def empty[A]: StreamingT[F, A] =
StreamingT.empty
def combine[A](xs: StreamingT[F, A], ys: StreamingT[F, A]): StreamingT[F, A] =
def combineK[A](xs: StreamingT[F, A], ys: StreamingT[F, A]): StreamingT[F, A] =
xs %::: ys
override def filter[A](fa: StreamingT[F, A])(f: A => Boolean): StreamingT[F, A] =
fa.filter(f)
Expand Down
4 changes: 2 additions & 2 deletions core/src/main/scala/cats/data/WriterT.scala
Original file line number Diff line number Diff line change
Expand Up @@ -188,8 +188,8 @@ private[data] sealed trait WriterTMonad[F[_], L] extends WriterTApplicative[F, L
private[data] sealed trait WriterTSemigroupK[F[_], L] extends SemigroupK[WriterT[F, L, ?]] {
implicit def F0: SemigroupK[F]

def combine[A](x: WriterT[F, L, A], y: WriterT[F, L, A]): WriterT[F, L, A] =
WriterT(F0.combine(x.run, y.run))
def combineK[A](x: WriterT[F, L, A], y: WriterT[F, L, A]): WriterT[F, L, A] =
WriterT(F0.combineK(x.run, y.run))
}

private[data] sealed trait WriterTMonoidK[F[_], L] extends MonoidK[WriterT[F, L, ?]] with WriterTSemigroupK[F, L] {
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/scala/cats/data/XorT.scala
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ private[data] trait XorTMonadError[F[_], L] extends MonadError[XorT[F, L, ?], L]
private[data] trait XorTSemigroupK[F[_], L] extends SemigroupK[XorT[F, L, ?]] {
implicit val F: Monad[F]
implicit val L: Semigroup[L]
def combine[A](x: XorT[F, L, A], y: XorT[F, L, A]): XorT[F, L, A] =
def combineK[A](x: XorT[F, L, A], y: XorT[F, L, A]): XorT[F, L, A] =
XorT(F.flatMap(x.value) {
case Xor.Left(l1) => F.map(y.value) {
case Xor.Left(l2) => Xor.Left(L.combine(l1, l2))
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/scala/cats/std/function.scala
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ private[std] sealed trait Function1Monoid[A, B] extends Monoid[A => B] with Func
}

private[std] sealed trait Function1SemigroupK extends SemigroupK[Lambda[A => A => A]] {
override def combine[A](x: A => A, y: A => A): A => A = x compose y
override def combineK[A](x: A => A, y: A => A): A => A = x compose y
}

private[std] sealed trait Function1MonoidK extends MonoidK[Lambda[A => A => A]] with Function1SemigroupK {
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/scala/cats/std/list.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ trait ListInstances extends ListInstances1 {

def empty[A]: List[A] = Nil

def combine[A](x: List[A], y: List[A]): List[A] = x ++ y
def combineK[A](x: List[A], y: List[A]): List[A] = x ++ y

def pure[A](x: A): List[A] = x :: Nil

Expand Down
2 changes: 1 addition & 1 deletion core/src/main/scala/cats/std/option.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ trait OptionInstances extends OptionInstances1 {

def empty[A]: Option[A] = None

def combine[A](x: Option[A], y: Option[A]): Option[A] = x orElse y
def combineK[A](x: Option[A], y: Option[A]): Option[A] = x orElse y

def pure[A](x: A): Option[A] = Some(x)

Expand Down
2 changes: 1 addition & 1 deletion core/src/main/scala/cats/std/set.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ trait SetInstances extends algebra.std.SetInstances {

def empty[A]: Set[A] = Set.empty[A]

def combine[A](x: Set[A], y: Set[A]): Set[A] = x | y
def combineK[A](x: Set[A], y: Set[A]): Set[A] = x | y

def foldLeft[A, B](fa: Set[A], b: B)(f: (B, A) => B): B =
fa.foldLeft(b)(f)
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/scala/cats/std/stream.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ trait StreamInstances {

def empty[A]: Stream[A] = Stream.Empty

def combine[A](x: Stream[A], y: Stream[A]): Stream[A] = x #::: y
def combineK[A](x: Stream[A], y: Stream[A]): Stream[A] = x #::: y

def pure[A](x: A): Stream[A] = Stream(x)

Expand Down
2 changes: 1 addition & 1 deletion core/src/main/scala/cats/std/vector.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ trait VectorInstances {

def empty[A]: Vector[A] = Vector.empty[A]

def combine[A](x: Vector[A], y: Vector[A]): Vector[A] = x ++ y
def combineK[A](x: Vector[A], y: Vector[A]): Vector[A] = x ++ y

def pure[A](x: A): Vector[A] = Vector(x)

Expand Down
25 changes: 12 additions & 13 deletions docs/src/main/tut/semigroupk.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,32 +64,31 @@ takes a concrete type, like `Int`, and returns a concrete type:
*`, whereas `Int` would have kind `*` and `Map` would have kind `*,* -> *`,
and, in fact, the `K` in `SemigroupK` stands for `Kind`.

For `List`, the `Semigroup` and `SemigroupK` instance's `combine`
operation are both list concatenation:
For `List`, the `Semigroup` instance's `combine` operation and the `SemigroupK`
instance's `combineK` operation are both list concatenation:

```tut
SemigroupK[List].combine(List(1,2,3), List(4,5,6)) == Semigroup[List[Int]].combine(List(1,2,3), List(4,5,6))
SemigroupK[List].combineK(List(1,2,3), List(4,5,6)) == Semigroup[List[Int]].combine(List(1,2,3), List(4,5,6))
```

However for `Option`, `Semigroup` and `SemigroupK`'s `combine` operation
differs. Since `Semigroup` operates on fully specified types, a
`Semigroup[Option[A]]` knows the concrete type of `A` and will
use `Semigroup[A].combine` to combine the inner `A`s. Consequently,
`Semigroup[Option[A]].combine` requires an implicit
`Semigroup[A]`.
However for `Option`, the `Semigroup`'s `combine` and the `SemigroupK`'s
`combineK` operation differ. Since `Semigroup` operates on fully specified
types, a `Semigroup[Option[A]]` knows the concrete type of `A` and will use
`Semigroup[A].combine` to combine the inner `A`s. Consequently,
`Semigroup[Option[A]].combine` requires an implicit `Semigroup[A]`.

In contrast, since `SemigroupK[Option]` operates on `Option` where
the inner type is not fully specified and can be anything (i.e. is
"universally quantified"). Thus, we cannot know how to `combine`
two of them. Therefore, in the case of `Option` the
`SemigroupK[Option].combine` method has no choice but to use the
`SemigroupK[Option].combineK` method has no choice but to use the
`orElse` method of Option:

```tut
Semigroup[Option[Int]].combine(Some(1), Some(2))
SemigroupK[Option].combine(Some(1), Some(2))
SemigroupK[Option].combine(Some(1), None)
SemigroupK[Option].combine(None, Some(2))
SemigroupK[Option].combineK(Some(1), Some(2))
SemigroupK[Option].combineK(Some(1), None)
SemigroupK[Option].combineK(None, Some(2))
```

There is inline syntax available for both `Semigroup` and
Expand Down
2 changes: 1 addition & 1 deletion laws/src/main/scala/cats/laws/MonadCombineLaws.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ trait MonadCombineLaws[F[_]] extends MonadFilterLaws[F] with AlternativeLaws[F]
implicit override def F: MonadCombine[F]

def monadCombineLeftDistributivity[A, B](fa: F[A], fa2: F[A], f: A => F[B]): IsEq[F[B]] =
F.combine(fa, fa2).flatMap(f) <-> F.combine(fa flatMap f, fa2 flatMap f)
F.combineK(fa, fa2).flatMap(f) <-> F.combineK(fa flatMap f, fa2 flatMap f)
}

object MonadCombineLaws {
Expand Down
4 changes: 2 additions & 2 deletions laws/src/main/scala/cats/laws/MonoidKLaws.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ trait MonoidKLaws[F[_]] extends SemigroupKLaws[F] {
override implicit def F: MonoidK[F]

def monoidKLeftIdentity[A](a: F[A]): IsEq[F[A]] =
F.combine(F.empty, a) <-> a
F.combineK(F.empty, a) <-> a

def monoidKRightIdentity[A](a: F[A]): IsEq[F[A]] =
F.combine(a, F.empty) <-> a
F.combineK(a, F.empty) <-> a
}

object MonoidKLaws {
Expand Down
2 changes: 1 addition & 1 deletion laws/src/main/scala/cats/laws/SemigroupKLaws.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ trait SemigroupKLaws[F[_]] {
implicit def F: SemigroupK[F]

def semigroupKAssociative[A](a: F[A], b: F[A], c: F[A]): IsEq[F[A]] =
F.combine(F.combine(a, b), c) <-> F.combine(a, F.combine(b, c))
F.combineK(F.combineK(a, b), c) <-> F.combineK(a, F.combineK(b, c))
}

object SemigroupKLaws {
Expand Down
8 changes: 4 additions & 4 deletions tests/src/test/scala/cats/tests/ListWrapper.scala
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ object ListWrapper {

val semigroupK: SemigroupK[ListWrapper] =
new SemigroupK[ListWrapper] {
def combine[A](x: ListWrapper[A], y: ListWrapper[A]): ListWrapper[A] =
ListWrapper(SemigroupK[List].combine(x.list, y.list))
def combineK[A](x: ListWrapper[A], y: ListWrapper[A]): ListWrapper[A] =
ListWrapper(SemigroupK[List].combineK(x.list, y.list))
}

def semigroup[A]: Semigroup[ListWrapper[A]] = semigroupK.algebra[A]
Expand All @@ -79,8 +79,8 @@ object ListWrapper {

def empty[A]: ListWrapper[A] = ListWrapper(M.empty[A])

def combine[A](x: ListWrapper[A], y: ListWrapper[A]): ListWrapper[A] =
ListWrapper(M.combine(x.list, y.list))
def combineK[A](x: ListWrapper[A], y: ListWrapper[A]): ListWrapper[A] =
ListWrapper(M.combineK(x.list, y.list))
}
}

Expand Down