Skip to content

Commit

Permalink
Merge pull request #2 from tschuchortdev/fix_classcast
Browse files Browse the repository at this point in the history
Fix ClassCastException in TraverseK
  • Loading branch information
tschuchortdev authored Nov 28, 2024
2 parents e3dba10 + 9e7ce42 commit 6f11cc2
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 8 deletions.
9 changes: 5 additions & 4 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ ThisBuild / scalacOptions ++= Seq(
"-language:experimental.macros",
"-language:implicitConversions",
"-language:higherKinds",
"-language:namedTypeArguments",
"-language:saferExceptions",
//"-language:namedTypeArguments",
//"-language:saferExceptions",
"-language:dynamics",
"-language:numericLiterals",
// "-Ykind-projector:underscores",
//"-language:numericLiterals",
"-Xkind-projector:underscores",
"-unchecked",
// "-Ysafe-init", // Note: causes warnings when used with Shapeless 3 recursive derivation
// "-Yexplicit-nulls", // Make reference types non-nullable: String != String|Null
Expand Down Expand Up @@ -99,6 +99,7 @@ lazy val root = (project in file("."))
"org.typelevel" %% "mouse" % "1.3.1", // helper functions
"org.typelevel" %% "kittens" % "3.3.0", // type class derivation
"org.typelevel" %% "cats-collections-core" % "0.9.8",
"org.typelevel" %% "cats-effect" % "3.5.7"
).map(_ % Test),

Test / parallelExecution := true
Expand Down
9 changes: 6 additions & 3 deletions src/main/scala/BasicTypeclasses.scala
Original file line number Diff line number Diff line change
Expand Up @@ -293,10 +293,13 @@ object TraverseK {
given adtTraverseK[D[_[_]]](using pInst: K11.Instances[TraverseK, D]): TraverseK[D] with {
extension [F[_]](df: D[F])
override def traverseK[G[+_], H[_]](f: [A] => F[A] => G[H[A]])(using Applicative[G]): G[D[H]] =
pInst.traverse(df)(Applicative[G].map.asInstanceOf[shapeless3.deriving.MapF[G]])(
Applicative[G].pure.asInstanceOf[shapeless3.deriving.Pure[G]]
pInst.traverse(df)(
([A, B] => (ga: G[A], ab: A => B) => Applicative[G].map(ga)(ab)).asInstanceOf[shapeless3.deriving.MapF[G]]
)(
[A] => (a: A) => Applicative[G].pure(a)
)(
[A, B] => (gg: G[A => B], ga: G[A]) => Applicative[G].ap(gg)(ga)
)(
Applicative[G].ap.asInstanceOf[shapeless3.deriving.Ap[G]])(
[t[_[_]]] => (fieldTraversableK: TraverseK[t], field: t[F]) => fieldTraversableK.traverseK(field)(f)
)
}
Expand Down
16 changes: 15 additions & 1 deletion src/test/scala/TypeclassesTest.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
package com.tschuchort.hkd

import cats.Show
import cats.{Applicative, Id, Show}
import cats.data.Const
import cats.data.Writer
import cats.effect.IO
import com.tschuchort.hkd.internal.`.`
import cats.syntax.all
import cats.effect.unsafe.implicits.global

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

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

0 comments on commit 6f11cc2

Please sign in to comment.