Skip to content

Commit 0e57d12

Browse files
authored
Merge branch 'main' into add-scaladoc-links
2 parents ce1cb53 + 52c58d2 commit 0e57d12

File tree

6 files changed

+238
-180
lines changed

6 files changed

+238
-180
lines changed

CONTRIBUTING.md

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -189,14 +189,9 @@ The documentation for this website is stored alongside the source, in the [docs
189189

190190
### Generating the Site
191191

192-
The microsite generation requires a specific scala version that might
193-
differ from the project's one. We strongly suggest to check the CI's
194-
workflow to discover the proper version:
195-
[CI scala-version matrix](https://github.com/typelevel/cats/blob/main/.github/workflows/ci.yml#L230) and [CI makeMicrosite
196-
command](https://github.com/typelevel/cats/blob/main/.github/workflows/ci.yml#L281)
197-
198-
At the moment the command is:
199-
`sbt ++2.12.15 docs/tlSite`
192+
The command is: `sbt docs/tlSite`
193+
194+
We suggest checking the CI's workflow to discover any changes at [CI site job](https://github.com/typelevel/cats/blob/v2.9.0/.github/workflows/ci.yml#L418).
200195

201196
### Previewing the site
202197

build.sbt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,7 @@ lazy val docs = project
285285
import laika.rewrite.link._
286286

287287
laikaConfig.value.withRawContent
288+
.withConfigValue("version", mdocVariables.value("VERSION"))
288289
.withConfigValue(
289290
LinkConfig(apiLinks =
290291
List(
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
/*
2+
* Copyright (c) 2015 Typelevel
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining a copy of
5+
* this software and associated documentation files (the "Software"), to deal in
6+
* the Software without restriction, including without limitation the rights to
7+
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
8+
* the Software, and to permit persons to whom the Software is furnished to do so,
9+
* subject to the following conditions:
10+
*
11+
* The above copyright notice and this permission notice shall be included in all
12+
* copies or substantial portions of the Software.
13+
*
14+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
16+
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
17+
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
18+
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19+
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20+
*/
21+
22+
package cats
23+
24+
import cats.Foldable.Source
25+
import cats.data.NonEmptyList
26+
27+
/**
28+
* This class defines a `Reducible[F]` in terms of a `Foldable[G]`
29+
* together with a `split` method, `F[A]` => `(A, G[A])`.
30+
*
31+
* This class can be used on any type where the first value (`A`) and
32+
* the "rest" of the values (`G[A]`) can be easily found.
33+
*
34+
* This class is only a helper, does not define a typeclass and should not be used outside of Cats.
35+
* Also see the discussion: PR #3541 and issue #3069.
36+
*/
37+
abstract class NonEmptyReducible[F[_], G[_]](implicit G: Foldable[G]) extends Reducible[F] {
38+
def split[A](fa: F[A]): (A, G[A])
39+
40+
def foldLeft[A, B](fa: F[A], b: B)(f: (B, A) => B): B = {
41+
val (a, ga) = split(fa)
42+
G.foldLeft(ga, f(b, a))(f)
43+
}
44+
45+
def foldRight[A, B](fa: F[A], lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] =
46+
Always(split(fa)).flatMap { case (a, ga) =>
47+
f(a, G.foldRight(ga, lb)(f))
48+
}
49+
50+
def reduceLeftTo[A, B](fa: F[A])(f: A => B)(g: (B, A) => B): B = {
51+
val (a, ga) = split(fa)
52+
G.foldLeft(ga, f(a))((b, a) => g(b, a))
53+
}
54+
55+
def reduceRightTo[A, B](fa: F[A])(f: A => B)(g: (A, Eval[B]) => Eval[B]): Eval[B] = {
56+
def loop(now: A, source: Source[A]): Eval[B] =
57+
source.uncons match {
58+
case Some((next, s)) => g(now, Eval.defer(loop(next, s.value)))
59+
case None => Eval.later(f(now))
60+
}
61+
62+
Always(split(fa)).flatMap { case (a, ga) =>
63+
Eval.defer(loop(a, Foldable.Source.fromFoldable(ga)))
64+
}
65+
}
66+
67+
override def size[A](fa: F[A]): Long = {
68+
val (_, tail) = split(fa)
69+
1 + G.size(tail)
70+
}
71+
72+
override def get[A](fa: F[A])(idx: Long): Option[A] =
73+
if (idx == 0L) Some(split(fa)._1) else G.get(split(fa)._2)(idx - 1L)
74+
75+
override def fold[A](fa: F[A])(implicit A: Monoid[A]): A = {
76+
val (a, ga) = split(fa)
77+
A.combine(a, G.fold(ga))
78+
}
79+
80+
override def foldM[H[_], A, B](fa: F[A], z: B)(f: (B, A) => H[B])(implicit H: Monad[H]): H[B] = {
81+
val (a, ga) = split(fa)
82+
H.flatMap(f(z, a))(G.foldM(ga, _)(f))
83+
}
84+
85+
override def find[A](fa: F[A])(f: A => Boolean): Option[A] = {
86+
val (a, ga) = split(fa)
87+
if (f(a)) Some(a) else G.find(ga)(f)
88+
}
89+
90+
override def exists[A](fa: F[A])(p: A => Boolean): Boolean = {
91+
val (a, ga) = split(fa)
92+
p(a) || G.exists(ga)(p)
93+
}
94+
95+
override def forall[A](fa: F[A])(p: A => Boolean): Boolean = {
96+
val (a, ga) = split(fa)
97+
p(a) && G.forall(ga)(p)
98+
}
99+
100+
override def toList[A](fa: F[A]): List[A] = {
101+
val (a, ga) = split(fa)
102+
a :: G.toList(ga)
103+
}
104+
105+
override def toNonEmptyList[A](fa: F[A]): NonEmptyList[A] = {
106+
val (a, ga) = split(fa)
107+
NonEmptyList(a, G.toList(ga))
108+
}
109+
110+
override def filter_[A](fa: F[A])(p: A => Boolean): List[A] = {
111+
val (a, ga) = split(fa)
112+
val filteredTail = G.filter_(ga)(p)
113+
if (p(a)) a :: filteredTail else filteredTail
114+
}
115+
116+
override def takeWhile_[A](fa: F[A])(p: A => Boolean): List[A] = {
117+
val (a, ga) = split(fa)
118+
if (p(a)) a :: G.takeWhile_(ga)(p) else Nil
119+
}
120+
121+
override def dropWhile_[A](fa: F[A])(p: A => Boolean): List[A] = {
122+
val (a, ga) = split(fa)
123+
if (p(a)) G.dropWhile_(ga)(p) else a :: G.toList(ga)
124+
}
125+
}

core/src/main/scala/cats/Reducible.scala

Lines changed: 0 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -435,103 +435,3 @@ object Reducible {
435435
object nonInheritedOps extends ToReducibleOps
436436

437437
}
438-
439-
/**
440-
* This class defines a `Reducible[F]` in terms of a `Foldable[G]`
441-
* together with a `split` method, `F[A]` => `(A, G[A])`.
442-
*
443-
* This class can be used on any type where the first value (`A`) and
444-
* the "rest" of the values (`G[A]`) can be easily found.
445-
*
446-
* This class is only a helper, does not define a typeclass and should not be used outside of Cats.
447-
* Also see the discussion: PR #3541 and issue #3069.
448-
*/
449-
abstract class NonEmptyReducible[F[_], G[_]](implicit G: Foldable[G]) extends Reducible[F] {
450-
def split[A](fa: F[A]): (A, G[A])
451-
452-
def foldLeft[A, B](fa: F[A], b: B)(f: (B, A) => B): B = {
453-
val (a, ga) = split(fa)
454-
G.foldLeft(ga, f(b, a))(f)
455-
}
456-
457-
def foldRight[A, B](fa: F[A], lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] =
458-
Always(split(fa)).flatMap { case (a, ga) =>
459-
f(a, G.foldRight(ga, lb)(f))
460-
}
461-
462-
def reduceLeftTo[A, B](fa: F[A])(f: A => B)(g: (B, A) => B): B = {
463-
val (a, ga) = split(fa)
464-
G.foldLeft(ga, f(a))((b, a) => g(b, a))
465-
}
466-
467-
def reduceRightTo[A, B](fa: F[A])(f: A => B)(g: (A, Eval[B]) => Eval[B]): Eval[B] = {
468-
def loop(now: A, source: Source[A]): Eval[B] =
469-
source.uncons match {
470-
case Some((next, s)) => g(now, Eval.defer(loop(next, s.value)))
471-
case None => Eval.later(f(now))
472-
}
473-
474-
Always(split(fa)).flatMap { case (a, ga) =>
475-
Eval.defer(loop(a, Foldable.Source.fromFoldable(ga)))
476-
}
477-
}
478-
479-
override def size[A](fa: F[A]): Long = {
480-
val (_, tail) = split(fa)
481-
1 + G.size(tail)
482-
}
483-
484-
override def get[A](fa: F[A])(idx: Long): Option[A] =
485-
if (idx == 0L) Some(split(fa)._1) else G.get(split(fa)._2)(idx - 1L)
486-
487-
override def fold[A](fa: F[A])(implicit A: Monoid[A]): A = {
488-
val (a, ga) = split(fa)
489-
A.combine(a, G.fold(ga))
490-
}
491-
492-
override def foldM[H[_], A, B](fa: F[A], z: B)(f: (B, A) => H[B])(implicit H: Monad[H]): H[B] = {
493-
val (a, ga) = split(fa)
494-
H.flatMap(f(z, a))(G.foldM(ga, _)(f))
495-
}
496-
497-
override def find[A](fa: F[A])(f: A => Boolean): Option[A] = {
498-
val (a, ga) = split(fa)
499-
if (f(a)) Some(a) else G.find(ga)(f)
500-
}
501-
502-
override def exists[A](fa: F[A])(p: A => Boolean): Boolean = {
503-
val (a, ga) = split(fa)
504-
p(a) || G.exists(ga)(p)
505-
}
506-
507-
override def forall[A](fa: F[A])(p: A => Boolean): Boolean = {
508-
val (a, ga) = split(fa)
509-
p(a) && G.forall(ga)(p)
510-
}
511-
512-
override def toList[A](fa: F[A]): List[A] = {
513-
val (a, ga) = split(fa)
514-
a :: G.toList(ga)
515-
}
516-
517-
override def toNonEmptyList[A](fa: F[A]): NonEmptyList[A] = {
518-
val (a, ga) = split(fa)
519-
NonEmptyList(a, G.toList(ga))
520-
}
521-
522-
override def filter_[A](fa: F[A])(p: A => Boolean): List[A] = {
523-
val (a, ga) = split(fa)
524-
val filteredTail = G.filter_(ga)(p)
525-
if (p(a)) a :: filteredTail else filteredTail
526-
}
527-
528-
override def takeWhile_[A](fa: F[A])(p: A => Boolean): List[A] = {
529-
val (a, ga) = split(fa)
530-
if (p(a)) a :: G.takeWhile_(ga)(p) else Nil
531-
}
532-
533-
override def dropWhile_[A](fa: F[A])(p: A => Boolean): List[A] = {
534-
val (a, ga) = split(fa)
535-
if (p(a)) G.dropWhile_(ga)(p) else a :: G.toList(ga)
536-
}
537-
}

0 commit comments

Comments
 (0)