Skip to content

Instantly share code, notes, and snippets.

@bishabosha
Created November 15, 2021 15:20
Show Gist options
  • Save bishabosha/f8d8e95f8ea0253f84969692eea01034 to your computer and use it in GitHub Desktop.
Save bishabosha/f8d8e95f8ea0253f84969692eea01034 to your computer and use it in GitHub Desktop.
Summon a Semigroup for Maybe, defined as an enum
// using scala 3.1.0
// using lib org.typelevel::cats-core:2.6.1
package good
import cats.Semigroup
import cats.syntax.all.*
enum Maybe[+A]:
case Just(a: A)
case Nothing
given [A: Semigroup]: Semigroup[Maybe[A]] with
def combine(a1: Maybe[A], a2: Maybe[A]): Maybe[A] =
(a1, a2) match
case (Maybe.Nothing, _) => Maybe.Nothing
case (_, Maybe.Nothing) => Maybe.Nothing
case (a1 @ Maybe.Just(_), a2 @ Maybe.Just(_)) => a1.combine(a2)
given [A: Semigroup]: Semigroup[Maybe.Just[A]] with
def combine(a1: Maybe.Just[A], a2: Maybe.Just[A]): Maybe.Just[A] =
val Maybe.Just(x) = a1
val Maybe.Just(y) = a2
Maybe.Just(x combine y)
@main def Main =
println(Maybe.Just(1) combine Maybe.Just(2))
println((Maybe.Nothing: Maybe[Int]) combine Maybe.Just(2))
@bishabosha
Copy link
Author

issue with this is that derives clauses will only define a single given for an enum - perhaps the compiler can be adapted to derive a given for each case?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment