Skip to content

Instantly share code, notes, and snippets.

@lbialy
Created October 19, 2024 19:37
Show Gist options
  • Save lbialy/395beb9998112427944bba8a29c803ba to your computer and use it in GitHub Desktop.
Save lbialy/395beb9998112427944bba8a29c803ba to your computer and use it in GitHub Desktop.
Kyo passes monadic laws via Discipline
//> using scala 3.5.1
//> using test.dep org.typelevel::cats-laws:2.12.0
//> using test.dep org.typelevel::discipline-munit:2.0.0
//> using test.dep io.getkyo::kyo-core:0.13.1
//> using test.dep io.getkyo::kyo-cats:0.13.1
//> using test.dep org.scalameta::munit:1.0.2
package kyo
import kyo.*
import kyo.Frame
import kyo.< as Pending
import cats.*
import cats.laws.discipline.MonadTests
import munit.DisciplineSuite
object stuff:
type KyoIO[A] = Pending[A, Any]
given Frame = Frame.internal
given Monad[KyoIO] = new Monad[KyoIO]:
def pure[A](a: A): KyoIO[A] = a
def flatMap[A, B](fa: KyoIO[A])(f: A => KyoIO[B]): KyoIO[B] = fa.flatMap(f)
def tailRecM[A, B](a: A)(f: A => KyoIO[Either[A, B]]): KyoIO[B] =
def recEval(r: KyoIO[Either[A, B]]): KyoIO[B] =
r.flatMap {
case Left(a) => recEval(f(a)).asInstanceOf[B < Any]
case Right(b) => pure(b)
}
recEval(f(a))
import org.scalacheck.{Arbitrary, Gen}
given arbKyo[A: Arbitrary]: Arbitrary[KyoIO[A]] =
Arbitrary(Arbitrary.arbitrary[A].asInstanceOf[Gen[KyoIO[A]]])
given kyoEq[A](using Eq[A], Flat[A]): Eq[KyoIO[A]] = Eq.by(_.eval)
import stuff.{*, given}
class KyoMonadLawTests extends DisciplineSuite {
checkAll("Kyo.MonadLaws", MonadTests[KyoIO].monad[Int, Int, String])
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment