最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

scala - Check a list contains an instance of each possible case class - Stack Overflow

programmeradmin0浏览0评论

In scala 3, say that I have code such as:

sealed trait Shape

final case class Circle(radius:Float) extends Shape
final case class Square(side:Float) extends Shape
final case class Rectangle(width: Float, height: Float) extends Shape

How can I define a method such as:

def listContainsAtLeastOneOfEach(shapes:List[Shape]): Boolean = ???

that returns true when the passed in list contains at least one instance of each descendant, and false if some descendant is missing, without having to manually maintain a list of the descendants within the method.

I'm trying already to do something with scala.deriving.Mirror.SumOf but I can't pin it down. I'm open to using macros if necessary, though I feel this should be doable with just inlining.

In scala 3, say that I have code such as:

sealed trait Shape

final case class Circle(radius:Float) extends Shape
final case class Square(side:Float) extends Shape
final case class Rectangle(width: Float, height: Float) extends Shape

How can I define a method such as:

def listContainsAtLeastOneOfEach(shapes:List[Shape]): Boolean = ???

that returns true when the passed in list contains at least one instance of each descendant, and false if some descendant is missing, without having to manually maintain a list of the descendants within the method.

I'm trying already to do something with scala.deriving.Mirror.SumOf but I can't pin it down. I'm open to using macros if necessary, though I feel this should be doable with just inlining.

Share Improve this question asked Jan 30 at 15:39 Angel BlancoAngel Blanco 7037 silver badges19 bronze badges 1
  • Could be interesting to use enum in Scala 3: stackoverflow/questions/69743692/… – Gaël J Commented Jan 30 at 18:36
Add a comment  | 

1 Answer 1

Reset to default 1

You could indeed use scala.deriving.Mirror.SumOf along with its ordinal() method:

import scalapiletime.constValue
import scala.deriving.*

inline def listContainsAtLeastOneOfSubtype[T](list: List[T])(using m: Mirror.SumOf[T]): Boolean =
  val ordinals: Set[Int] = list.foldLeft(Set.empty) { (ords, elem) =>
    ords + m.ordinal(elem)
  }
  val nSubtypes = constValue[Tuple.Size[m.MirroredElemTypes]]
  ordinals.size == nSubtypes

(Of course, the above still can be optimized, e.g. by stopping to iterate over the list once we know it will return true.)

发布评论

评论列表(0)

  1. 暂无评论