You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

嵌套类型类场景下Magnolia类型推导失败问题求助

错误原因

基于Magnolia实现的zio-schema在推导泛型密封特质(sealed trait)的Schema实例时,要求满足两个规则:

  1. 密封特质的所有子类型必须全部定义在密封特质自身的伴生对象中
  2. 对应的Schema隐式实例必须定义在密封特质的伴生对象作用域内,不能嵌套定义在子类型的代码块中
    你之前将RandomDoubleSchema放在RandomDouble这个子类型的内部,作用域封闭,Magnolia扫描Random特质的子类型时无法捕获到对应的实例,因此抛出找不到子类型的错误。

解决方案

按以下规则调整代码即可:

  • 将密封特质对应的Schema隐式定义移到自身伴生对象层级,不要嵌套在子类型内部
  • 使用时直接从伴生对象导入隐式实例,无需重复调用DeriveSchema.gen推导
  • 如果需要支持泛型推导,可在伴生对象内定义泛型隐式方法

调整后可运行的代码如下:

package dsl
import zio.schema._

sealed trait Random[A] {
  def generate: A
}

object Random {
  case object RandomDouble extends Random[Double] {
    override def generate: Double = ???
  }
  // Schema定义移到Random伴生对象层级
  implicit val randomDoubleSchema: Schema[Random[Double]] = DeriveSchema.gen[Random[Double]]
  
  // 若后续需要支持更多参数类型的Random推导,可补充泛型隐式方法
  // implicit def genericRandomSchema[A: Schema]: Schema[Random[A]] = DeriveSchema.gen[Random[A]]
}

sealed trait DummyExpr[A] {
  def eval(value: DummyExpr[A]): A
}

object DummyExpr {
  case object DummyTrue  extends DummyExpr[Boolean] {
    override def eval(value: DummyExpr[Boolean]): Boolean = ???
  }
  case object DummyFalse extends DummyExpr[Boolean] {
    override def eval(value: DummyExpr[Boolean]): Boolean = ???
  }

  case class DummyOperator[A](random: Random[A], predicate: DummyExpr[Boolean]) extends DummyExpr[A] {
    override def eval(value: DummyExpr[A]): A = ???
  }
  // DummyExpr的Schema同样放在自身伴生对象中
  implicit val dummyExprDoubleSchema: Schema[DummyExpr[Double]] = DeriveSchema.gen[DummyExpr[Double]]
}

object main extends App {
  import Random._
  import DummyExpr._
  val schemaRandom = implicitly[Schema[Random[Double]]]
  val schemaDummy  = implicitly[Schema[DummyExpr[Double]]]
}

内容的提问来源于stack exchange,提问作者cauchy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 17:15:02