Skip to content

Commit 6f11cc2

Browse files
Merge pull request #2 from tschuchortdev/fix_classcast
Fix ClassCastException in TraverseK
2 parents e3dba10 + 9e7ce42 commit 6f11cc2

File tree

3 files changed

+26
-8
lines changed

3 files changed

+26
-8
lines changed

build.sbt

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@ ThisBuild / scalacOptions ++= Seq(
1717
"-language:experimental.macros",
1818
"-language:implicitConversions",
1919
"-language:higherKinds",
20-
"-language:namedTypeArguments",
21-
"-language:saferExceptions",
20+
//"-language:namedTypeArguments",
21+
//"-language:saferExceptions",
2222
"-language:dynamics",
23-
"-language:numericLiterals",
24-
// "-Ykind-projector:underscores",
23+
//"-language:numericLiterals",
24+
"-Xkind-projector:underscores",
2525
"-unchecked",
2626
// "-Ysafe-init", // Note: causes warnings when used with Shapeless 3 recursive derivation
2727
// "-Yexplicit-nulls", // Make reference types non-nullable: String != String|Null
@@ -99,6 +99,7 @@ lazy val root = (project in file("."))
9999
"org.typelevel" %% "mouse" % "1.3.1", // helper functions
100100
"org.typelevel" %% "kittens" % "3.3.0", // type class derivation
101101
"org.typelevel" %% "cats-collections-core" % "0.9.8",
102+
"org.typelevel" %% "cats-effect" % "3.5.7"
102103
).map(_ % Test),
103104

104105
Test / parallelExecution := true

src/main/scala/BasicTypeclasses.scala

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -293,10 +293,13 @@ object TraverseK {
293293
given adtTraverseK[D[_[_]]](using pInst: K11.Instances[TraverseK, D]): TraverseK[D] with {
294294
extension [F[_]](df: D[F])
295295
override def traverseK[G[+_], H[_]](f: [A] => F[A] => G[H[A]])(using Applicative[G]): G[D[H]] =
296-
pInst.traverse(df)(Applicative[G].map.asInstanceOf[shapeless3.deriving.MapF[G]])(
297-
Applicative[G].pure.asInstanceOf[shapeless3.deriving.Pure[G]]
296+
pInst.traverse(df)(
297+
([A, B] => (ga: G[A], ab: A => B) => Applicative[G].map(ga)(ab)).asInstanceOf[shapeless3.deriving.MapF[G]]
298+
)(
299+
[A] => (a: A) => Applicative[G].pure(a)
300+
)(
301+
[A, B] => (gg: G[A => B], ga: G[A]) => Applicative[G].ap(gg)(ga)
298302
)(
299-
Applicative[G].ap.asInstanceOf[shapeless3.deriving.Ap[G]])(
300303
[t[_[_]]] => (fieldTraversableK: TraverseK[t], field: t[F]) => fieldTraversableK.traverseK(field)(f)
301304
)
302305
}

src/test/scala/TypeclassesTest.scala

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
package com.tschuchort.hkd
22

3-
import cats.Show
3+
import cats.{Applicative, Id, Show}
44
import cats.data.Const
5+
import cats.data.Writer
6+
import cats.effect.IO
7+
import com.tschuchort.hkd.internal.`.`
8+
import cats.syntax.all
9+
import cats.effect.unsafe.implicits.global
510

611
class TypeclassesTest extends munit.FunSuite {
712
sealed trait FooHK[F[_]]
@@ -109,4 +114,13 @@ class TypeclassesTest extends munit.FunSuite {
109114
case _ => throw AssertionError(s"Expected Contra21HK, was: $mapped")
110115
}
111116

117+
test("TraverseK sequences effects") {
118+
case class BarHK[F[_]](a: F[Int], b: F[Int], c: F[Int])
119+
var res = ""
120+
// Have to use IO here because Writer won't type-check for some reason
121+
val bar = BarHK[IO `.` Option](IO { res += "1"; Some(1) }, IO { res += "2"; Some(2) }, IO { res += "3"; Some(3) })
122+
val bar2 = TraverseK[BarHK].sequenceK(bar).unsafeRunSync()
123+
assertEquals(res, "123")
124+
assertEquals(bar2, BarHK[Option](Some(1), Some(2), Some(3)))
125+
}
112126
}

0 commit comments

Comments
 (0)