Skip to content

Commit 6bf8d45

Browse files
authored
Merge branch 'main' into scala3-style-imports
2 parents 6ef3e78 + 92b972b commit 6bf8d45

File tree

17 files changed

+445
-76
lines changed

17 files changed

+445
-76
lines changed

.git-blame-ignore-revs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,6 @@ f025b0198d55d7f5c09ee976eec9e274d8dd0309
1515

1616
# Scala Steward: Reformat with scalafmt 3.5.9
1717
b4d207e9fa9f1463f0827fe20101e7901fecf820
18+
19+
# Scala Steward: Reformat with scalafmt 3.8.4
20+
42490f49d2a62289c8ca0a57357f323982eeb93b

.github/workflows/ci.yml

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ concurrency:
2424

2525
jobs:
2626
build:
27-
name: Build and Test
27+
name: Test
2828
strategy:
2929
matrix:
30-
os: [ubuntu-latest]
30+
os: [ubuntu-22.04]
3131
scala: [2.12, 2.13, 3]
3232
java: [temurin@8, temurin@17, graalvm@21]
3333
project: [catsNative, catsJS, catsJVM]
@@ -51,14 +51,14 @@ jobs:
5151
runs-on: ${{ matrix.os }}
5252
timeout-minutes: 60
5353
steps:
54-
- name: Install sbt
55-
uses: sbt/setup-sbt@v1
56-
5754
- name: Checkout current branch (full)
5855
uses: actions/checkout@v4
5956
with:
6057
fetch-depth: 0
6158

59+
- name: Setup sbt
60+
uses: sbt/setup-sbt@v1
61+
6262
- name: Setup Java (temurin@8)
6363
id: setup-java-temurin-8
6464
if: matrix.java == 'temurin@8'
@@ -102,7 +102,7 @@ jobs:
102102
run: sbt githubWorkflowCheck
103103

104104
- name: Check headers and formatting
105-
if: matrix.java == 'temurin@8' && matrix.os == 'ubuntu-latest'
105+
if: matrix.java == 'temurin@8' && matrix.os == 'ubuntu-22.04'
106106
run: sbt 'project ${{ matrix.project }}' '++ ${{ matrix.scala }}' headerCheckAll scalafmtCheckAll 'project /' scalafmtSbtCheck
107107

108108
- name: nativeLink
@@ -117,11 +117,11 @@ jobs:
117117
run: sbt 'project ${{ matrix.project }}' '++ ${{ matrix.scala }}' test
118118

119119
- name: Check binary compatibility
120-
if: matrix.java == 'temurin@8' && matrix.os == 'ubuntu-latest'
120+
if: matrix.java == 'temurin@8' && matrix.os == 'ubuntu-22.04'
121121
run: sbt 'project ${{ matrix.project }}' '++ ${{ matrix.scala }}' mimaReportBinaryIssues
122122

123123
- name: Generate API documentation
124-
if: matrix.java == 'temurin@8' && matrix.os == 'ubuntu-latest'
124+
if: matrix.java == 'temurin@8' && matrix.os == 'ubuntu-22.04'
125125
run: sbt 'project ${{ matrix.project }}' '++ ${{ matrix.scala }}' doc
126126

127127
- name: Make target directories
@@ -145,18 +145,18 @@ jobs:
145145
if: github.event_name != 'pull_request' && (startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/main')
146146
strategy:
147147
matrix:
148-
os: [ubuntu-latest]
148+
os: [ubuntu-22.04]
149149
java: [temurin@8]
150150
runs-on: ${{ matrix.os }}
151151
steps:
152-
- name: Install sbt
153-
uses: sbt/setup-sbt@v1
154-
155152
- name: Checkout current branch (full)
156153
uses: actions/checkout@v4
157154
with:
158155
fetch-depth: 0
159156

157+
- name: Setup sbt
158+
uses: sbt/setup-sbt@v1
159+
160160
- name: Setup Java (temurin@8)
161161
id: setup-java-temurin-8
162162
if: matrix.java == 'temurin@8'
@@ -315,18 +315,18 @@ jobs:
315315
if: github.event.repository.fork == false && github.event_name != 'pull_request'
316316
strategy:
317317
matrix:
318-
os: [ubuntu-latest]
318+
os: [ubuntu-22.04]
319319
java: [temurin@8]
320320
runs-on: ${{ matrix.os }}
321321
steps:
322-
- name: Install sbt
323-
uses: sbt/setup-sbt@v1
324-
325322
- name: Checkout current branch (full)
326323
uses: actions/checkout@v4
327324
with:
328325
fetch-depth: 0
329326

327+
- name: Setup sbt
328+
uses: sbt/setup-sbt@v1
329+
330330
- name: Setup Java (temurin@8)
331331
id: setup-java-temurin-8
332332
if: matrix.java == 'temurin@8'
@@ -376,7 +376,7 @@ jobs:
376376
name: Validate Steward Config
377377
strategy:
378378
matrix:
379-
os: [ubuntu-latest]
379+
os: [ubuntu-22.04]
380380
java: [temurin@11]
381381
runs-on: ${{ matrix.os }}
382382
steps:
@@ -401,18 +401,18 @@ jobs:
401401
name: Generate Site
402402
strategy:
403403
matrix:
404-
os: [ubuntu-latest]
404+
os: [ubuntu-22.04]
405405
java: [temurin@17]
406406
runs-on: ${{ matrix.os }}
407407
steps:
408-
- name: Install sbt
409-
uses: sbt/setup-sbt@v1
410-
411408
- name: Checkout current branch (full)
412409
uses: actions/checkout@v4
413410
with:
414411
fetch-depth: 0
415412

413+
- name: Setup sbt
414+
uses: sbt/setup-sbt@v1
415+
416416
- name: Setup Java (temurin@8)
417417
id: setup-java-temurin-8
418418
if: matrix.java == 'temurin@8'
@@ -467,18 +467,18 @@ jobs:
467467
name: Scalafix
468468
strategy:
469469
matrix:
470-
os: [ubuntu-latest]
470+
os: [ubuntu-22.04]
471471
java: [temurin@8]
472472
runs-on: ${{ matrix.os }}
473473
steps:
474-
- name: Install sbt
475-
uses: sbt/setup-sbt@v1
476-
477474
- name: Checkout current branch (full)
478475
uses: actions/checkout@v4
479476
with:
480477
fetch-depth: 0
481478

479+
- name: Setup sbt
480+
uses: sbt/setup-sbt@v1
481+
482482
- name: Setup Java (temurin@8)
483483
id: setup-java-temurin-8
484484
if: matrix.java == 'temurin@8'

.scalafmt.conf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
version=3.8.2
1+
version=3.8.6
22
align.openParenCallSite = true
33
align.openParenDefnSite = true
44
maxColumn = 120

alleycats-core/src/main/scala/alleycats/syntax/all.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,4 @@
2121

2222
package alleycats.syntax
2323

24-
object all extends EmptySyntax with FoldableSyntax
24+
object all extends EmptySyntax with FoldableSyntax with ExtractSyntax
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
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 alleycats
23+
package syntax
24+
25+
import alleycats.Extract
26+
27+
object extract extends ExtractSyntax
28+
29+
trait ExtractSyntax {
30+
implicit final def catsSyntaxExtract[F[_], A](fa: F[A]): ExtractOps[F, A] = new ExtractOps[F, A](fa)
31+
}
32+
33+
final private[alleycats] class ExtractOps[F[_], A](private val fa: F[A]) extends AnyVal {
34+
def extract(implicit F: Extract[F]): A = F.extract(fa)
35+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
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 alleycats
23+
24+
import cats.{Eq, Foldable}
25+
import alleycats.syntax.all.{catsSyntaxExtract, EmptyOps, ExtraFoldableOps}
26+
27+
/**
28+
* Test that our syntax implicits are working.
29+
*
30+
* Each method should correspond to one type class worth of syntax.
31+
* Ideally, we should be testing every operator or method that we
32+
* expect to add to generic parameters. This file is a safeguard
33+
* against accidentally breaking (or removing) syntax which was
34+
* otherwise untested.
35+
*
36+
* The strategy here is to create "mock" values of particular types,
37+
* and then ensure that the syntax we want is available. We never plan
38+
* to run any of these methods, so we don't need real values. All
39+
* values in the methods should be generic -- we rely on parametricity
40+
* to guarantee that the syntax will be available for any type with
41+
* the proper type class instance(s).
42+
*
43+
* None of these tests should ever run, or do any runtime checks.
44+
*/
45+
object SyntaxSuite {
46+
47+
// pretend we have a value of type A
48+
def mock[A]: A = ???
49+
50+
def testEmpty[A: Empty]: Unit = {
51+
val x = mock[A]
52+
implicit val y: Eq[A] = mock[Eq[A]]
53+
val a0: Boolean = x.isEmpty
54+
val a1: Boolean = x.nonEmpty
55+
}
56+
57+
def testFoldable[F[_]: Foldable, A]: Unit = {
58+
val x = mock[F[A]]
59+
val y = mock[A => Unit]
60+
x.foreach(y)
61+
}
62+
63+
def testExtract[F[_]: Extract, A]: Unit = {
64+
val x = mock[F[A]]
65+
val y = x.extract
66+
}
67+
}

build.sbt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
ThisBuild / tlBaseVersion := "2.12"
1+
ThisBuild / tlBaseVersion := "2.13"
22

33
val scalaCheckVersion = "1.18.1"
44

55
val disciplineVersion = "1.7.0"
66

77
val disciplineMunitVersion = "2.0.0"
88

9-
val munitVersion = "1.0.3"
9+
val munitVersion = "1.1.0"
1010

1111
val PrimaryJava = JavaSpec.temurin("8")
1212
val LTSJava = JavaSpec.temurin("17")
@@ -15,7 +15,7 @@ val GraalVM = JavaSpec.graalvm("21")
1515
ThisBuild / githubWorkflowJavaVersions := Seq(PrimaryJava, LTSJava, GraalVM)
1616

1717
val Scala212 = "2.12.20"
18-
val Scala213 = "2.13.15"
18+
val Scala213 = "2.13.16"
1919
val Scala3 = "3.3.4"
2020

2121
ThisBuild / crossScalaVersions := Seq(Scala212, Scala213, Scala3)

core/src/main/scala-2.12/cats/data/ChainCompanionCompat.scala

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,17 @@ private[data] trait ChainCompanionCompat {
3838
}
3939

4040
private def fromImmutableSeq[A](s: immutable.Seq[A]): Chain[A] = {
41-
if (s.isEmpty) nil
42-
else if (s.lengthCompare(1) == 0) one(s.head)
43-
else Wrap(s)
41+
val lc = s.lengthCompare(1)
42+
if (lc < 0) nil
43+
else if (lc > 0) Wrap(s)
44+
else one(s.head)
4445
}
4546

4647
private def fromMutableSeq[A](s: Seq[A]): Chain[A] = {
47-
if (s.isEmpty) nil
48-
else if (s.lengthCompare(1) == 0) one(s.head)
49-
else Wrap(s.toVector)
48+
val lc = s.lengthCompare(1)
49+
if (lc < 0) nil
50+
else if (lc > 0) Wrap(s.toVector)
51+
else one(s.head)
5052
}
5153

5254
/**

core/src/main/scala-2.13+/cats/data/ChainCompanionCompat.scala

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,12 @@ private[data] trait ChainCompanionCompat {
2828
/**
2929
* Creates a Chain from the specified sequence.
3030
*/
31-
def fromSeq[A](s: Seq[A]): Chain[A] =
32-
if (s.isEmpty) nil
33-
else if (s.lengthCompare(1) == 0) one(s.head)
34-
else Wrap(s)
31+
def fromSeq[A](s: Seq[A]): Chain[A] = {
32+
val lc = s.lengthCompare(1)
33+
if (lc < 0) nil
34+
else if (lc > 0) Wrap(s)
35+
else one(s.head)
36+
}
3537

3638
/**
3739
* Creates a Chain from the specified IterableOnce.

0 commit comments

Comments
 (0)