Skip to content

Typeclass Different from the Derived type #510

Open
@agaro1121

Description

@agaro1121

This question is for Scala3

Is there any way for the Typeclass to be different than the derived type?

For example:

trait Thing[A]
trait OtherThing[A]

object Thing extends Derivation[???] {
  type Typeclass[A] = OtherThing[A]

   override def join[T](caseClass: CaseClass[OtherThing, T]): Thing[T] = ???
   override def split[T](sealedTrait: SealedTrait[OtherThing, T]): Thing[T] = ???
}

// usage

Thing.derive[SomeA]

We do something similar to this in Scala 2 to generate an Gen[List[A]] that holds exactly one instance of an arbitrary for every sub type in a sealed trait. This is extremely useful for testing.

Here's the implementation that works in Scala 2:

object FullList {
  type Typeclass[A] = Arbitrary[A]

  def join[A](ctx: CaseClass[Arbitrary, A]): Gen[List[A]] =
    ctx
      .constructMonadic(p => Gen.lzy(p.typeclass))
      .map(a => List(a))

  def split[A](ctx: SealedTrait[Arbitrary, A]): Gen[List[A]] =
    ctx.subtypes.toList
      .foldLeft(Gen.const(List.empty[A])) { (acc, next) =>
        acc.flatMap { xs => Gen.lzy(next.typeclass.arbitrary).map(_ :: xs) }
      }

  def gen[A]: Gen[List[A]] = macro Magnolia.gen[A]
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions