gpt4 book ai didi

scala - 使用 Shapeless 进行类型级过滤

转载 作者:行者123 更新时间:2023-12-01 04:47:23 24 4
gpt4 key购买 nike

有谁知道如何使用 Shapeless 进行此测试。

package net.jtownson.swakka.jsonschema

import org.scalatest.FlatSpec
import org.scalatest.Matchers._

class OptionalFieldSpec extends FlatSpec {

case class A(i: Int, j: Option[Int])

"an extractor of some kind" should "get the (non)optional fields from a case class" in {

extractNonOptionalFieldNames[A] shouldBe List("i")

extractOptionalFieldNames[A] shouldBe List("j")

}

def extractNonOptionalFieldNames[T <: Product](/* implicit typeclass instances? */): List[String] = ???

def extractOptionalFieldNames[T <: Product]: List[String] = ???

}

我没有 A 的运行时实例或其通用等效项,因为我正在为案例类 A 创建 JsonSchema,它独立于任何给定实例。该架构有一个必填字段,它是非可选字段的列表。例如

{
"type" -> "object",
"required" -> ["i"],
"properties" -> {
"i" -> {
"type" -> "integer",
"format" -> "int32"
}
}
}

最佳答案

类似这样的事情:

trait FieldNameExtractor[T] extends Serializable {
import shapeless.ops.hlist.{RightFolder, ToTraversable}
import shapeless.ops.record.Keys
import shapeless.{HList, HNil, LabelledGeneric, Poly2}

/**
* Extracts filtered field names for type [[T]],
* given a polymorphic function that acts as the type filter
*/
def extract[L <: HList, R <: HList, O <: HList](op: Poly2)(
implicit lgen: LabelledGeneric.Aux[T, L],
folder: RightFolder.Aux[L, HNil.type, op.type, R],
keys: Keys.Aux[R, O],
traversable: ToTraversable.Aux[O, List, Symbol]
): List[String] = {
val result = keys().to[List]
result.map(_.name)
}
}

object FieldNameExtractor {
def apply[T] = new FieldNameExtractor[T] {}
}

用法:

import org.scalatest.FlatSpec
import org.scalatest.Matchers._

class Test extends FlatSpec {
/* type filters */
import shapeless.{HList, Poly2}
import shapeless.labelled.KeyTag, shapeless.tag.Tagged

type FilterO[A, T] = Option[A] with KeyTag[Symbol with Tagged[T], Option[A]]

trait Ignore extends Poly2 {
implicit def default[A, L <: HList] = at[A, L]((_, l) => l)
}
trait Accept extends Poly2 {
implicit def default[A, L <: HList] = at[A, L](_ :: _)
}

object allOptions extends Ignore {
implicit def option[A, T, L <: HList] = at[FilterO[A, T], L](_ :: _)
}
object noOptions extends Accept {
implicit def option[A, T, L <: HList] = at[FilterO[A, T], L]((_, l) => l)
}

"an extractor of some kind" should "get the (non)optional fields from a case class" in {
case class A(i: Int, j: Option[Int], k: String)

val fne = FieldNameExtractor[A]
fne.extract(noOptions) shouldBe List("i", "k") // extractNonOptionalFieldNames
fne.extract(allOptions) shouldBe List("j") // extractOptionalFieldNames
}
}

关于scala - 使用 Shapeless 进行类型级过滤,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47360597/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com